5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool-ms.h>
40 #include <mono/metadata/threadpool-ms-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/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)
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array, MonoClassField *field_handle, MonoError *error)
846 mono_error_init (error);
848 MonoClass *klass = mono_handle_class (array);
849 guint32 size = mono_array_element_size (klass);
850 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
852 const char *field_data;
854 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
855 mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type");
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 mono_error_set_argument (error, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle));
864 size *= MONO_HANDLE_GETVAL(array, max_length);
865 field_data = mono_field_get_data (field_handle);
867 if (size > mono_type_size (field_handle->type, &align)) {
868 mono_error_set_argument (error, "field_handle", "Field not large enough to fill array");
872 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
874 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
875 guint ## n *src = (guint ## n *) field_data; \
877 nEnt = (size / sizeof(guint ## n)); \
879 for (i = 0; i < nEnt; i++) { \
880 data[i] = read ## n (&src[i]); \
884 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
886 switch (type->type) {
903 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
907 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
912 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
914 return offsetof (MonoString, chars);
917 ICALL_EXPORT MonoObject *
918 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
920 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
924 MonoObject *ret = mono_object_clone_checked (obj, &error);
925 mono_error_set_pending_exception (&error);
932 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
938 MONO_CHECK_ARG_NULL (handle,);
940 klass = mono_class_from_mono_type (handle);
941 MONO_CHECK_ARG (handle, klass,);
943 if (mono_class_is_gtd (klass))
946 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
947 if (!is_ok (&error)) {
948 mono_error_set_pending_exception (&error);
952 /* This will call the type constructor */
953 if (!mono_runtime_class_init_full (vtable, &error))
954 mono_error_set_pending_exception (&error);
958 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
962 mono_image_check_for_module_cctor (image);
963 if (image->has_module_cctor) {
964 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
965 if (!mono_error_ok (&error)) {
966 mono_error_set_pending_exception (&error);
969 /*It's fine to raise the exception here*/
970 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
971 if (!is_ok (&error)) {
972 mono_error_set_pending_exception (&error);
975 if (!mono_runtime_class_init_full (vtable, &error))
976 mono_error_set_pending_exception (&error);
980 ICALL_EXPORT MonoBoolean
981 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
983 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
984 // It does not work on win32
990 MonoInternalThread *thread;
992 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
993 /* if we have no info we are optimistic and assume there is enough room */
997 thread = mono_thread_internal_current ();
998 // .net seems to check that at least 50% of stack is available
999 min_size = thread->stack_size / 2;
1001 // TODO: It's not always set
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionType *
1216 ves_icall_System_Object_GetType (MonoObject *obj)
1219 MonoReflectionType *ret;
1220 #ifndef DISABLE_REMOTING
1221 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1222 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1225 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1227 mono_error_set_pending_exception (&error);
1232 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1234 MonoMethod **dest = (MonoMethod **)data;
1236 /* skip unmanaged frames */
1241 if (!strcmp (m->klass->name_space, "System.Reflection"))
1250 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1252 MonoMethod **dest = (MonoMethod **)data;
1254 /* skip unmanaged frames */
1258 if (m->wrapper_type != MONO_WRAPPER_NONE)
1266 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1277 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1279 MonoMethod **dest = (MonoMethod **)data;
1281 /* skip unmanaged frames */
1285 if (m->wrapper_type != MONO_WRAPPER_NONE)
1293 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1294 || (!strcmp (m->klass->name_space, "System"))))
1304 static MonoReflectionType *
1305 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1307 MonoMethod *m, *dest;
1309 MonoType *type = NULL;
1310 MonoAssembly *assembly = NULL;
1311 gboolean type_resolve = FALSE;
1312 MonoImage *rootimage = NULL;
1314 mono_error_init (error);
1317 * We must compute the calling assembly as type loading must happen under a metadata context.
1318 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1319 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1321 m = mono_method_get_last_managed ();
1323 if (m && m->klass->image != mono_defaults.corlib) {
1324 /* Happens with inlining */
1326 /* Ugly hack: type_from_parsed_name is called from
1327 * System.Type.internal_from_name, which is called most
1328 * directly from System.Type.GetType(string,bool,bool) but
1329 * also indirectly from places such as
1330 * System.Type.GetType(string,func,func) (via
1331 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1332 * so we need to skip over all of those to find the true caller.
1334 * It would be nice if we had stack marks.
1336 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1342 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1343 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1344 * to crash. This only seems to happen in some strange remoting
1345 * scenarios and I was unable to figure out what's happening there.
1346 * Dec 10, 2005 - Martin.
1350 assembly = dest->klass->image->assembly;
1351 type_resolve = TRUE;
1352 rootimage = assembly->image;
1354 g_warning (G_STRLOC);
1356 *caller_assembly = assembly;
1358 if (info->assembly.name)
1359 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1362 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1363 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1364 return_val_if_nok (error, NULL);
1368 // Say we're looking for System.Generic.Dict<int, Local>
1369 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1370 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1371 // is messed up when we go to construct the Local as the type arg...
1373 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1374 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1375 if (!info->assembly.name && !type) {
1377 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1378 return_val_if_nok (error, NULL);
1380 if (assembly && !type && type_resolve) {
1381 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1382 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1383 return_val_if_nok (error, NULL);
1389 return mono_type_get_object_checked (mono_domain_get (), type, error);
1392 ICALL_EXPORT MonoReflectionType*
1393 ves_icall_System_Type_internal_from_name (MonoString *name,
1394 MonoBoolean throwOnError,
1395 MonoBoolean ignoreCase)
1398 MonoTypeNameParse info;
1399 MonoReflectionType *type = NULL;
1401 MonoAssembly *caller_assembly;
1403 char *str = mono_string_to_utf8_checked (name, &error);
1404 if (!is_ok (&error))
1407 parsedOk = mono_reflection_parse_type (str, &info);
1409 /* mono_reflection_parse_type() mangles the string */
1411 mono_reflection_free_type_info (&info);
1413 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1417 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1419 if (!is_ok (&error)) {
1420 mono_reflection_free_type_info (&info);
1426 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1428 if (info.assembly.name)
1429 aname = mono_stringify_assembly_name (&info.assembly);
1430 else if (caller_assembly)
1431 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1433 aname = g_strdup ("");
1434 mono_error_set_type_load_name (&error, tname, aname, "");
1436 mono_reflection_free_type_info (&info);
1442 if (!is_ok (&error)) {
1444 mono_error_set_pending_exception (&error);
1446 mono_error_cleanup (&error);
1454 ICALL_EXPORT MonoReflectionType*
1455 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1458 MonoReflectionType *ret;
1459 MonoDomain *domain = mono_domain_get ();
1461 ret = mono_type_get_object_checked (domain, handle, &error);
1462 mono_error_set_pending_exception (&error);
1467 ICALL_EXPORT MonoType*
1468 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1470 return mono_class_get_type (klass);
1474 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1476 g_ptr_array_free (ptr_array, TRUE);
1480 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1486 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1489 char *res = mono_string_to_utf8_checked (s, &error);
1490 mono_error_set_pending_exception (&error);
1494 /* System.TypeCode */
1513 TYPECODE_STRING = 18
1516 ICALL_EXPORT guint32
1517 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1519 int t = type->type->type;
1521 if (type->type->byref)
1522 return TYPECODE_OBJECT;
1526 case MONO_TYPE_VOID:
1527 return TYPECODE_OBJECT;
1528 case MONO_TYPE_BOOLEAN:
1529 return TYPECODE_BOOLEAN;
1531 return TYPECODE_BYTE;
1533 return TYPECODE_SBYTE;
1535 return TYPECODE_UINT16;
1537 return TYPECODE_INT16;
1538 case MONO_TYPE_CHAR:
1539 return TYPECODE_CHAR;
1543 return TYPECODE_OBJECT;
1545 return TYPECODE_UINT32;
1547 return TYPECODE_INT32;
1549 return TYPECODE_UINT64;
1551 return TYPECODE_INT64;
1553 return TYPECODE_SINGLE;
1555 return TYPECODE_DOUBLE;
1556 case MONO_TYPE_VALUETYPE: {
1557 MonoClass *klass = type->type->data.klass;
1559 if (klass->enumtype) {
1560 t = mono_class_enum_basetype (klass)->type;
1562 } else if (mono_is_corlib_image (klass->image)) {
1563 if (strcmp (klass->name_space, "System") == 0) {
1564 if (strcmp (klass->name, "Decimal") == 0)
1565 return TYPECODE_DECIMAL;
1566 else if (strcmp (klass->name, "DateTime") == 0)
1567 return TYPECODE_DATETIME;
1570 return TYPECODE_OBJECT;
1572 case MONO_TYPE_STRING:
1573 return TYPECODE_STRING;
1574 case MONO_TYPE_SZARRAY:
1575 case MONO_TYPE_ARRAY:
1576 case MONO_TYPE_OBJECT:
1578 case MONO_TYPE_MVAR:
1579 case MONO_TYPE_TYPEDBYREF:
1580 return TYPECODE_OBJECT;
1581 case MONO_TYPE_CLASS:
1583 MonoClass *klass = type->type->data.klass;
1584 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1585 if (strcmp (klass->name, "DBNull") == 0)
1586 return TYPECODE_DBNULL;
1589 return TYPECODE_OBJECT;
1590 case MONO_TYPE_GENERICINST:
1591 return TYPECODE_OBJECT;
1593 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1599 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1601 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1602 return mono_class_enum_basetype (type->data.klass);
1603 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1604 return mono_class_enum_basetype (type->data.generic_class->container_class);
1608 ICALL_EXPORT guint32
1609 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1614 g_assert (type != NULL);
1616 klass = mono_class_from_mono_type (type->type);
1617 klassc = mono_class_from_mono_type (c->type);
1619 if (type->type->byref ^ c->type->byref)
1622 if (type->type->byref) {
1623 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1624 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1626 klass = mono_class_from_mono_type (t);
1627 klassc = mono_class_from_mono_type (ot);
1629 if (mono_type_is_primitive (t)) {
1630 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1631 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1632 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1633 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1634 return t->type == ot->type;
1636 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1639 if (klass->valuetype)
1640 return klass == klassc;
1641 return klass->valuetype == klassc->valuetype;
1644 return mono_class_is_assignable_from (klass, klassc);
1647 ICALL_EXPORT guint32
1648 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1651 MonoClass *klass = mono_class_from_mono_type (type->type);
1652 mono_class_init_checked (klass, &error);
1653 if (!is_ok (&error)) {
1654 mono_error_set_pending_exception (&error);
1657 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1658 mono_error_set_pending_exception (&error);
1662 ICALL_EXPORT guint32
1663 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1665 MonoClass *klass = mono_class_from_mono_type (type->type);
1666 return mono_class_get_flags (klass);
1669 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1670 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1673 MonoClass *klass = field->field->parent;
1674 MonoMarshalType *info;
1678 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1679 if (mono_class_is_gtd (klass) ||
1680 (gklass && gklass->context.class_inst->is_open))
1683 ftype = mono_field_get_type (field->field);
1684 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1687 info = mono_marshal_load_type_info (klass);
1689 for (i = 0; i < info->num_fields; ++i) {
1690 if (info->fields [i].field == field->field) {
1691 if (!info->fields [i].mspec)
1694 MonoReflectionMarshalAsAttribute* obj;
1695 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1696 if (!mono_error_ok (&error))
1697 mono_error_set_pending_exception (&error);
1706 ICALL_EXPORT MonoReflectionField*
1707 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1710 gboolean found = FALSE;
1716 klass = handle->parent;
1718 klass = mono_class_from_mono_type (type);
1720 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1723 /* The managed code will throw the exception */
1727 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1728 mono_error_set_pending_exception (&error);
1732 ICALL_EXPORT MonoReflectionEvent*
1733 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1741 klass = handle->parent;
1743 klass = mono_class_from_mono_type (type);
1745 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1747 /* Managed code will throw an exception */
1751 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1752 mono_error_set_pending_exception (&error);
1757 ICALL_EXPORT MonoReflectionProperty*
1758 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1766 klass = handle->parent;
1768 klass = mono_class_from_mono_type (type);
1770 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1772 /* Managed code will throw an exception */
1776 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1777 mono_error_set_pending_exception (&error);
1781 ICALL_EXPORT MonoArray*
1782 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1785 MonoType *type = mono_field_get_type_checked (field->field, &error);
1788 if (!mono_error_ok (&error)) {
1789 mono_error_set_pending_exception (&error);
1793 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1794 mono_error_set_pending_exception (&error);
1799 vell_icall_get_method_attributes (MonoMethod *method)
1801 return method->flags;
1805 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1808 MonoReflectionType *rt;
1809 MonoDomain *domain = mono_domain_get ();
1810 MonoMethodSignature* sig;
1812 sig = mono_method_signature_checked (method, &error);
1813 if (!mono_error_ok (&error)) {
1814 mono_error_set_pending_exception (&error);
1818 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1819 if (!mono_error_ok (&error)) {
1820 mono_error_set_pending_exception (&error);
1824 MONO_STRUCT_SETREF (info, parent, rt);
1826 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1827 if (!mono_error_ok (&error)) {
1828 mono_error_set_pending_exception (&error);
1832 MONO_STRUCT_SETREF (info, ret, rt);
1834 info->attrs = method->flags;
1835 info->implattrs = method->iflags;
1836 if (sig->call_convention == MONO_CALL_DEFAULT)
1837 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1839 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1844 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1847 ICALL_EXPORT MonoArray*
1848 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1851 MonoDomain *domain = mono_domain_get ();
1853 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1854 mono_error_set_pending_exception (&error);
1858 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1859 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1862 MonoDomain *domain = mono_domain_get ();
1863 MonoReflectionMarshalAsAttribute* res = NULL;
1864 MonoMarshalSpec **mspecs;
1867 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1868 mono_method_get_marshal_info (method, mspecs);
1871 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1872 if (!mono_error_ok (&error)) {
1873 mono_error_set_pending_exception (&error);
1878 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1880 mono_metadata_free_marshal_spec (mspecs [i]);
1887 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1889 MonoClass *parent = field->field->parent;
1890 mono_class_setup_fields (parent);
1892 return field->field->offset - sizeof (MonoObject);
1895 ICALL_EXPORT MonoReflectionType*
1896 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1899 MonoReflectionType *ret;
1902 parent = declaring? field->field->parent: field->klass;
1904 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1905 mono_error_set_pending_exception (&error);
1911 ICALL_EXPORT MonoObject *
1912 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1915 MonoClass *fklass = field->klass;
1916 MonoClassField *cf = field->field;
1917 MonoDomain *domain = mono_object_domain (field);
1919 if (fklass->image->assembly->ref_only) {
1920 mono_set_pending_exception (mono_get_exception_invalid_operation (
1921 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1925 if (mono_security_core_clr_enabled () &&
1926 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1927 mono_error_set_pending_exception (&error);
1931 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1932 mono_error_set_pending_exception (&error);
1937 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1940 MonoClassField *cf = field->field;
1944 if (field->klass->image->assembly->ref_only) {
1945 mono_set_pending_exception (mono_get_exception_invalid_operation (
1946 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1950 if (mono_security_core_clr_enabled () &&
1951 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1952 mono_error_set_pending_exception (&error);
1956 type = mono_field_get_type_checked (cf, &error);
1957 if (!mono_error_ok (&error)) {
1958 mono_error_set_pending_exception (&error);
1962 v = (gchar *) value;
1964 switch (type->type) {
1967 case MONO_TYPE_BOOLEAN:
1970 case MONO_TYPE_CHAR:
1979 case MONO_TYPE_VALUETYPE:
1982 v += sizeof (MonoObject);
1984 case MONO_TYPE_STRING:
1985 case MONO_TYPE_OBJECT:
1986 case MONO_TYPE_CLASS:
1987 case MONO_TYPE_ARRAY:
1988 case MONO_TYPE_SZARRAY:
1991 case MONO_TYPE_GENERICINST: {
1992 MonoGenericClass *gclass = type->data.generic_class;
1993 g_assert (!gclass->context.class_inst->is_open);
1995 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1996 MonoClass *nklass = mono_class_from_mono_type (type);
1997 MonoObject *nullable;
2000 * Convert the boxed vtype into a Nullable structure.
2001 * This is complicated by the fact that Nullables have
2002 * a variable structure.
2004 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2005 if (!mono_error_ok (&error)) {
2006 mono_error_set_pending_exception (&error);
2010 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2012 v = (gchar *)mono_object_unbox (nullable);
2015 if (gclass->container_class->valuetype && (v != NULL))
2016 v += sizeof (MonoObject);
2020 g_error ("type 0x%x not handled in "
2021 "ves_icall_FieldInfo_SetValueInternal", type->type);
2026 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2027 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2028 if (!is_ok (&error)) {
2029 mono_error_set_pending_exception (&error);
2032 if (!vtable->initialized) {
2033 if (!mono_runtime_class_init_full (vtable, &error)) {
2034 mono_error_set_pending_exception (&error);
2038 mono_field_static_set_value (vtable, cf, v);
2040 mono_field_set_value (obj, cf, v);
2045 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2054 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2055 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2059 if (MONO_TYPE_IS_REFERENCE (f->type))
2060 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2062 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2065 ICALL_EXPORT MonoObject *
2066 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2068 MonoObject *o = NULL;
2069 MonoClassField *field = rfield->field;
2071 MonoDomain *domain = mono_object_domain (rfield);
2073 MonoTypeEnum def_type;
2074 const char *def_value;
2078 mono_class_init (field->parent);
2080 t = mono_field_get_type_checked (field, &error);
2081 if (!mono_error_ok (&error)) {
2082 mono_error_set_pending_exception (&error);
2086 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2087 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2091 if (image_is_dynamic (field->parent->image)) {
2092 MonoClass *klass = field->parent;
2093 int fidx = field - klass->fields;
2094 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2096 g_assert (def_values);
2097 def_type = def_values [fidx].def_type;
2098 def_value = def_values [fidx].data;
2100 if (def_type == MONO_TYPE_END) {
2101 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2105 def_value = mono_class_get_field_default_value (field, &def_type);
2106 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2108 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2113 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2117 case MONO_TYPE_BOOLEAN:
2120 case MONO_TYPE_CHAR:
2128 case MONO_TYPE_R8: {
2131 /* boxed value type */
2132 t = g_new0 (MonoType, 1);
2134 klass = mono_class_from_mono_type (t);
2136 o = mono_object_new_checked (domain, klass, &error);
2137 if (!mono_error_ok (&error)) {
2138 mono_error_set_pending_exception (&error);
2141 v = ((gchar *) o) + sizeof (MonoObject);
2142 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2143 if (mono_error_set_pending_exception (&error))
2147 case MONO_TYPE_STRING:
2148 case MONO_TYPE_CLASS:
2149 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2150 if (mono_error_set_pending_exception (&error))
2154 g_assert_not_reached ();
2160 ICALL_EXPORT MonoReflectionType*
2161 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2164 MonoReflectionType *ret;
2167 type = mono_field_get_type_checked (ref_field->field, &error);
2168 if (!mono_error_ok (&error)) {
2169 mono_error_set_pending_exception (&error);
2173 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2174 if (!mono_error_ok (&error)) {
2175 mono_error_set_pending_exception (&error);
2182 /* From MonoProperty.cs */
2184 PInfo_Attributes = 1,
2185 PInfo_GetMethod = 1 << 1,
2186 PInfo_SetMethod = 1 << 2,
2187 PInfo_ReflectedType = 1 << 3,
2188 PInfo_DeclaringType = 1 << 4,
2193 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2196 MonoReflectionType *rt;
2197 MonoReflectionMethod *rm;
2198 MonoDomain *domain = mono_object_domain (property);
2199 const MonoProperty *pproperty = property->property;
2201 if ((req_info & PInfo_ReflectedType) != 0) {
2202 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2203 if (mono_error_set_pending_exception (&error))
2206 MONO_STRUCT_SETREF (info, parent, rt);
2208 if ((req_info & PInfo_DeclaringType) != 0) {
2209 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2210 if (mono_error_set_pending_exception (&error))
2213 MONO_STRUCT_SETREF (info, declaring_type, rt);
2216 if ((req_info & PInfo_Name) != 0)
2217 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2219 if ((req_info & PInfo_Attributes) != 0)
2220 info->attrs = pproperty->attrs;
2222 if ((req_info & PInfo_GetMethod) != 0) {
2223 if (pproperty->get &&
2224 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2225 pproperty->get->klass == property->klass)) {
2226 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2227 if (mono_error_set_pending_exception (&error))
2233 MONO_STRUCT_SETREF (info, get, rm);
2235 if ((req_info & PInfo_SetMethod) != 0) {
2236 if (pproperty->set &&
2237 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2238 pproperty->set->klass == property->klass)) {
2239 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2240 if (mono_error_set_pending_exception (&error))
2246 MONO_STRUCT_SETREF (info, set, rm);
2249 * There may be other methods defined for properties, though, it seems they are not exposed
2250 * in the reflection API
2255 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2258 MonoReflectionType *rt;
2259 MonoReflectionMethod *rm;
2260 MonoDomain *domain = mono_object_domain (event);
2262 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2263 if (mono_error_set_pending_exception (&error))
2266 MONO_STRUCT_SETREF (info, reflected_type, rt);
2268 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2269 if (mono_error_set_pending_exception (&error))
2272 MONO_STRUCT_SETREF (info, declaring_type, rt);
2274 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2275 info->attrs = event->event->attrs;
2277 if (event->event->add) {
2278 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2279 if (mono_error_set_pending_exception (&error))
2285 MONO_STRUCT_SETREF (info, add_method, rm);
2287 if (event->event->remove) {
2288 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2289 if (mono_error_set_pending_exception (&error))
2295 MONO_STRUCT_SETREF (info, remove_method, rm);
2297 if (event->event->raise) {
2298 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2299 if (mono_error_set_pending_exception (&error))
2305 MONO_STRUCT_SETREF (info, raise_method, rm);
2307 #ifndef MONO_SMALL_CONFIG
2308 if (event->event->other) {
2310 while (event->event->other [n])
2312 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2313 if (mono_error_set_pending_exception (&error))
2315 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2317 for (i = 0; i < n; i++) {
2318 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2319 if (mono_error_set_pending_exception (&error))
2321 mono_array_setref (info->other_methods, i, rm);
2328 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2333 mono_class_setup_interfaces (klass, error);
2334 if (!mono_error_ok (error))
2337 for (i = 0; i < klass->interface_count; i++) {
2338 ic = klass->interfaces [i];
2339 g_hash_table_insert (ifaces, ic, ic);
2341 collect_interfaces (ic, ifaces, error);
2342 if (!mono_error_ok (error))
2348 MonoArray *iface_array;
2349 MonoGenericContext *context;
2353 } FillIfaceArrayData;
2356 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2358 MonoReflectionType *rt;
2359 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2360 MonoClass *ic = (MonoClass *)key;
2361 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2363 if (!mono_error_ok (data->error))
2366 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2367 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2368 if (!mono_error_ok (data->error))
2372 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2373 if (!mono_error_ok (data->error))
2376 mono_array_setref (data->iface_array, data->next_idx++, rt);
2379 mono_metadata_free_type (inflated);
2383 get_interfaces_hash (gconstpointer v1)
2385 MonoClass *k = (MonoClass*)v1;
2387 return k->type_token;
2390 ICALL_EXPORT MonoArray*
2391 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2394 MonoClass *klass = mono_class_from_mono_type (type->type);
2396 FillIfaceArrayData data = { 0 };
2399 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2401 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2402 data.context = mono_class_get_context (klass);
2403 klass = mono_class_get_generic_class (klass)->container_class;
2406 for (parent = klass; parent; parent = parent->parent) {
2407 mono_class_setup_interfaces (parent, &error);
2408 if (!mono_error_ok (&error))
2410 collect_interfaces (parent, iface_hash, &error);
2411 if (!mono_error_ok (&error))
2415 data.error = &error;
2416 data.domain = mono_object_domain (type);
2418 len = g_hash_table_size (iface_hash);
2420 g_hash_table_destroy (iface_hash);
2421 if (!data.domain->empty_types) {
2422 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2423 if (!is_ok (&error))
2426 return data.domain->empty_types;
2429 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2430 if (!is_ok (&error))
2432 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2433 if (!mono_error_ok (&error))
2436 g_hash_table_destroy (iface_hash);
2437 return data.iface_array;
2440 g_hash_table_destroy (iface_hash);
2441 mono_error_set_pending_exception (&error);
2446 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2448 gboolean variance_used;
2449 MonoClass *klass = mono_class_from_mono_type (type->type);
2450 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2451 MonoReflectionMethod *member;
2454 int i = 0, len, ioffset;
2458 mono_class_init_checked (klass, &error);
2459 if (mono_error_set_pending_exception (&error))
2461 mono_class_init_checked (iclass, &error);
2462 if (mono_error_set_pending_exception (&error))
2465 mono_class_setup_vtable (klass);
2467 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2471 len = mono_class_num_methods (iclass);
2472 domain = mono_object_domain (type);
2473 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2474 if (mono_error_set_pending_exception (&error))
2476 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2477 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2478 if (mono_error_set_pending_exception (&error))
2480 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2482 while ((method = mono_class_get_methods (iclass, &iter))) {
2483 member = mono_method_get_object_checked (domain, method, iclass, &error);
2484 if (mono_error_set_pending_exception (&error))
2486 mono_array_setref (*methods, i, member);
2487 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2488 if (mono_error_set_pending_exception (&error))
2490 mono_array_setref (*targets, i, member);
2497 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2500 MonoClass *klass = mono_class_from_mono_type (type->type);
2502 mono_class_init_checked (klass, &error);
2503 if (mono_error_set_pending_exception (&error))
2506 if (image_is_dynamic (klass->image)) {
2507 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2508 *packing = tb->packing_size;
2509 *size = tb->class_size;
2511 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2515 ICALL_EXPORT MonoReflectionType*
2516 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2519 MonoReflectionType *ret;
2522 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2523 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2524 mono_error_set_pending_exception (&error);
2528 klass = mono_class_from_mono_type (type->type);
2529 mono_class_init_checked (klass, &error);
2530 if (mono_error_set_pending_exception (&error))
2534 // GetElementType should only return a type for:
2535 // Array Pointer PassedByRef
2536 if (type->type->byref)
2537 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2538 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2539 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2540 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2541 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2545 mono_error_set_pending_exception (&error);
2550 ICALL_EXPORT MonoReflectionType*
2551 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2554 MonoReflectionType *ret;
2556 if (type->type->byref)
2559 MonoClass *klass = mono_class_from_mono_type (type->type);
2563 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2564 mono_error_set_pending_exception (&error);
2569 ICALL_EXPORT MonoBoolean
2570 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2572 return type->type->type == MONO_TYPE_PTR;
2575 ICALL_EXPORT MonoBoolean
2576 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2578 return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
2581 ICALL_EXPORT MonoBoolean
2582 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2584 return type->type->byref;
2587 ICALL_EXPORT MonoBoolean
2588 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2591 MonoClass *klass = mono_class_from_mono_type (type->type);
2592 mono_class_init_checked (klass, &error);
2593 if (mono_error_set_pending_exception (&error))
2596 return mono_class_is_com_object (klass);
2599 ICALL_EXPORT guint32
2600 ves_icall_reflection_get_token (MonoObject* obj)
2603 guint32 result = mono_reflection_get_token_checked (obj, &error);
2604 mono_error_set_pending_exception (&error);
2608 ICALL_EXPORT MonoReflectionModuleHandle
2609 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2611 mono_error_init (error);
2612 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2613 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2614 MonoClass *klass = mono_class_from_mono_type (t);
2615 return mono_module_get_object_handle (domain, klass->image, error);
2618 ICALL_EXPORT MonoReflectionAssemblyHandle
2619 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2621 mono_error_init (error);
2622 MonoDomain *domain = mono_domain_get ();
2623 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2624 MonoClass *klass = mono_class_from_mono_type (t);
2625 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2628 ICALL_EXPORT MonoReflectionType*
2629 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2632 MonoReflectionType *ret;
2633 MonoDomain *domain = mono_domain_get ();
2636 if (type->type->byref)
2638 if (type->type->type == MONO_TYPE_VAR) {
2639 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2640 klass = param ? param->owner.klass : NULL;
2641 } else if (type->type->type == MONO_TYPE_MVAR) {
2642 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2643 klass = param ? param->owner.method->klass : NULL;
2645 klass = mono_class_from_mono_type (type->type)->nested_in;
2651 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2652 mono_error_set_pending_exception (&error);
2657 ICALL_EXPORT MonoStringHandle
2658 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2660 MonoDomain *domain = mono_domain_get ();
2661 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2662 MonoClass *klass = mono_class_from_mono_type (type);
2665 char *n = g_strdup_printf ("%s&", klass->name);
2666 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2672 return mono_string_new_handle (domain, klass->name, error);
2676 ICALL_EXPORT MonoStringHandle
2677 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2679 MonoDomain *domain = mono_domain_get ();
2680 MonoClass *klass = mono_class_from_mono_type_handle (type);
2682 while (klass->nested_in)
2683 klass = klass->nested_in;
2685 if (klass->name_space [0] == '\0')
2686 return NULL_HANDLE_STRING;
2688 return mono_string_new_handle (domain, klass->name_space, error);
2692 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2696 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2697 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2701 klass = mono_class_from_mono_type (type->type);
2707 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2709 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2712 ICALL_EXPORT MonoArray*
2713 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2716 MonoReflectionType *rt;
2718 MonoClass *klass, *pklass;
2719 MonoDomain *domain = mono_object_domain (type);
2722 klass = mono_class_from_mono_type (type->type);
2724 if (mono_class_is_gtd (klass)) {
2725 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2726 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2727 if (mono_error_set_pending_exception (&error))
2729 for (i = 0; i < container->type_argc; ++i) {
2730 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2732 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2733 if (mono_error_set_pending_exception (&error))
2736 mono_array_setref (res, i, rt);
2738 } else if (mono_class_is_ginst (klass)) {
2739 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2740 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2741 if (mono_error_set_pending_exception (&error))
2743 for (i = 0; i < inst->type_argc; ++i) {
2744 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2745 if (mono_error_set_pending_exception (&error))
2748 mono_array_setref (res, i, rt);
2756 ICALL_EXPORT gboolean
2757 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2761 if (!IS_MONOTYPE (type))
2764 if (type->type->byref)
2767 klass = mono_class_from_mono_type (type->type);
2768 return mono_class_is_gtd (klass);
2771 ICALL_EXPORT MonoReflectionType*
2772 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2775 MonoReflectionType *ret;
2778 if (type->type->byref)
2781 klass = mono_class_from_mono_type (type->type);
2783 if (mono_class_is_gtd (klass)) {
2784 return type; /* check this one */
2786 if (mono_class_is_ginst (klass)) {
2787 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2790 tb = mono_class_get_ref_info (generic_class);
2792 if (generic_class->wastypebuilder && tb)
2793 return (MonoReflectionType *)tb;
2795 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2796 mono_error_set_pending_exception (&error);
2804 ICALL_EXPORT MonoReflectionType*
2805 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2808 MonoReflectionType *ret;
2810 MonoType *geninst, **types;
2813 g_assert (IS_MONOTYPE (type));
2814 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2815 if (mono_error_set_pending_exception (&error))
2818 count = mono_array_length (type_array);
2819 types = g_new0 (MonoType *, count);
2821 for (i = 0; i < count; i++) {
2822 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2823 types [i] = t->type;
2826 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2829 mono_error_set_pending_exception (&error);
2833 klass = mono_class_from_mono_type (geninst);
2835 /*we might inflate to the GTD*/
2836 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2837 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2841 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2842 mono_error_set_pending_exception (&error);
2847 ICALL_EXPORT gboolean
2848 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2852 if (!IS_MONOTYPE (type))
2855 if (type->type->byref)
2858 klass = mono_class_from_mono_type (type->type);
2859 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2863 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2865 if (!IS_MONOTYPE (type))
2868 if (is_generic_parameter (type->type))
2869 return mono_type_get_generic_param_num (type->type);
2873 ICALL_EXPORT MonoGenericParamInfo *
2874 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2876 return mono_generic_param_info (type->type->data.generic_param);
2879 ICALL_EXPORT MonoBoolean
2880 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2882 return is_generic_parameter (type->type);
2885 ICALL_EXPORT MonoReflectionMethod*
2886 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2887 MonoReflectionMethod* generic)
2894 MonoReflectionMethod *ret = NULL;
2896 domain = ((MonoObject *)type)->vtable->domain;
2898 klass = mono_class_from_mono_type (type->type);
2899 mono_class_init_checked (klass, &error);
2900 if (mono_error_set_pending_exception (&error))
2904 while ((method = mono_class_get_methods (klass, &iter))) {
2905 if (method->token == generic->method->token) {
2906 ret = mono_method_get_object_checked (domain, method, klass, &error);
2907 if (mono_error_set_pending_exception (&error))
2915 ICALL_EXPORT MonoReflectionMethod *
2916 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2919 MonoType *type = ref_type->type;
2921 MonoReflectionMethod *ret = NULL;
2923 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2924 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2927 if (type->type == MONO_TYPE_VAR)
2930 method = mono_type_get_generic_param_owner (type)->owner.method;
2933 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2934 if (!mono_error_ok (&error))
2935 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2939 ICALL_EXPORT MonoBoolean
2940 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2942 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2946 ICALL_EXPORT MonoBoolean
2947 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2949 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2954 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2956 MonoDomain *domain = mono_domain_get ();
2957 MonoImage *image = method->method->klass->image;
2958 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2959 MonoTableInfo *tables = image->tables;
2960 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2961 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2962 guint32 im_cols [MONO_IMPLMAP_SIZE];
2963 guint32 scope_token;
2964 const char *import = NULL;
2965 const char *scope = NULL;
2967 if (image_is_dynamic (image)) {
2968 MonoReflectionMethodAux *method_aux =
2969 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2971 import = method_aux->dllentry;
2972 scope = method_aux->dll;
2975 if (!import || !scope) {
2976 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2981 if (piinfo->implmap_idx) {
2982 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2984 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2985 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2986 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2987 scope = mono_metadata_string_heap (image, scope_token);
2991 *flags = piinfo->piflags;
2992 *entry_point = mono_string_new (domain, import);
2993 *dll_name = mono_string_new (domain, scope);
2996 ICALL_EXPORT MonoReflectionMethod *
2997 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2999 MonoMethodInflated *imethod;
3001 MonoReflectionMethod *ret = NULL;
3004 if (method->method->is_generic)
3007 if (!method->method->is_inflated)
3010 imethod = (MonoMethodInflated *) method->method;
3012 result = imethod->declaring;
3013 /* Not a generic method. */
3014 if (!result->is_generic)
3017 if (image_is_dynamic (method->method->klass->image)) {
3018 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3019 MonoReflectionMethod *res;
3022 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3023 * the dynamic case as well ?
3025 mono_image_lock ((MonoImage*)image);
3026 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3027 mono_image_unlock ((MonoImage*)image);
3033 if (imethod->context.class_inst) {
3034 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3035 /*Generic methods gets the context of the GTD.*/
3036 if (mono_class_get_context (klass)) {
3037 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3038 if (!mono_error_ok (&error))
3043 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3045 if (!mono_error_ok (&error))
3046 mono_error_set_pending_exception (&error);
3050 ICALL_EXPORT gboolean
3051 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3053 return mono_method_signature (method->method)->generic_param_count != 0;
3056 ICALL_EXPORT gboolean
3057 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3059 return method->method->is_generic;
3062 ICALL_EXPORT MonoArray*
3063 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3066 MonoReflectionType *rt;
3071 domain = mono_object_domain (method);
3073 if (method->method->is_inflated) {
3074 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3077 count = inst->type_argc;
3078 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3079 if (mono_error_set_pending_exception (&error))
3082 for (i = 0; i < count; i++) {
3083 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3084 if (mono_error_set_pending_exception (&error))
3087 mono_array_setref (res, i, rt);
3094 count = mono_method_signature (method->method)->generic_param_count;
3095 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3096 if (mono_error_set_pending_exception (&error))
3099 for (i = 0; i < count; i++) {
3100 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3101 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3102 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3104 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3105 if (mono_error_set_pending_exception (&error))
3108 mono_array_setref (res, i, rt);
3114 ICALL_EXPORT MonoObject *
3115 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3119 * Invoke from reflection is supposed to always be a virtual call (the API
3120 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3121 * greater flexibility.
3123 MonoMethod *m = method->method;
3124 MonoMethodSignature *sig = mono_method_signature (m);
3127 void *obj = this_arg;
3131 if (mono_security_core_clr_enabled () &&
3132 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3133 mono_error_set_pending_exception (&error);
3137 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3138 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3139 mono_error_cleanup (&error); /* FIXME does this make sense? */
3140 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3145 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3146 if (!is_ok (&error)) {
3147 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3150 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3151 char *target_name = mono_type_get_full_name (m->klass);
3152 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3153 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3155 g_free (target_name);
3159 m = mono_object_get_virtual_method (this_arg, m);
3160 /* must pass the pointer to the value for valuetype methods */
3161 if (m->klass->valuetype)
3162 obj = mono_object_unbox (this_arg);
3163 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3164 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3169 if (sig->ret->byref) {
3170 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"));
3174 pcount = params? mono_array_length (params): 0;
3175 if (pcount != sig->param_count) {
3176 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3180 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3181 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."));
3185 image = m->klass->image;
3186 if (image->assembly->ref_only) {
3187 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."));
3191 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3192 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3196 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3200 intptr_t *lower_bounds;
3201 pcount = mono_array_length (params);
3202 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3203 /* Note: the synthetized array .ctors have int32 as argument type */
3204 for (i = 0; i < pcount; ++i)
3205 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3207 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3208 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3209 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3210 if (!mono_error_ok (&error)) {
3211 mono_error_set_pending_exception (&error);
3215 for (i = 0; i < mono_array_length (arr); ++i) {
3216 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3217 if (!mono_error_ok (&error)) {
3218 mono_error_set_pending_exception (&error);
3221 mono_array_setref_fast (arr, i, subarray);
3223 return (MonoObject*)arr;
3226 if (m->klass->rank == pcount) {
3227 /* Only lengths provided. */
3228 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3229 if (!mono_error_ok (&error)) {
3230 mono_error_set_pending_exception (&error);
3234 return (MonoObject*)arr;
3236 g_assert (pcount == (m->klass->rank * 2));
3237 /* The arguments are lower-bound-length pairs */
3238 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3240 for (i = 0; i < pcount / 2; ++i) {
3241 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3242 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3245 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3246 if (!mono_error_ok (&error)) {
3247 mono_error_set_pending_exception (&error);
3251 return (MonoObject*)arr;
3254 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3255 mono_error_set_pending_exception (&error);
3259 #ifndef DISABLE_REMOTING
3260 ICALL_EXPORT MonoObject *
3261 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3264 MonoDomain *domain = mono_object_domain (method);
3265 MonoMethod *m = method->method;
3266 MonoMethodSignature *sig = mono_method_signature (m);
3267 MonoArray *out_args;
3269 int i, j, outarg_count = 0;
3271 if (m->klass == mono_defaults.object_class) {
3272 if (!strcmp (m->name, "FieldGetter")) {
3273 MonoClass *k = this_arg->vtable->klass;
3277 /* If this is a proxy, then it must be a CBO */
3278 if (k == mono_defaults.transparent_proxy_class) {
3279 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3280 this_arg = tp->rp->unwrapped_server;
3281 g_assert (this_arg);
3282 k = this_arg->vtable->klass;
3285 name = mono_array_get (params, MonoString *, 1);
3286 str = mono_string_to_utf8_checked (name, &error);
3287 if (mono_error_set_pending_exception (&error))
3291 MonoClassField* field = mono_class_get_field_from_name (k, str);
3294 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3295 if (field_klass->valuetype) {
3296 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3297 if (mono_error_set_pending_exception (&error))
3300 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3302 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3303 if (mono_error_set_pending_exception (&error))
3305 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3306 mono_array_setref (out_args, 0, result);
3313 g_assert_not_reached ();
3315 } else if (!strcmp (m->name, "FieldSetter")) {
3316 MonoClass *k = this_arg->vtable->klass;
3322 /* If this is a proxy, then it must be a CBO */
3323 if (k == mono_defaults.transparent_proxy_class) {
3324 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3325 this_arg = tp->rp->unwrapped_server;
3326 g_assert (this_arg);
3327 k = this_arg->vtable->klass;
3330 name = mono_array_get (params, MonoString *, 1);
3331 str = mono_string_to_utf8_checked (name, &error);
3332 if (mono_error_set_pending_exception (&error))
3336 MonoClassField* field = mono_class_get_field_from_name (k, str);
3339 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3340 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3342 if (field_klass->valuetype) {
3343 size = mono_type_size (field->type, &align);
3344 g_assert (size == mono_class_value_size (field_klass, NULL));
3345 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3347 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3350 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3351 if (mono_error_set_pending_exception (&error))
3353 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3362 g_assert_not_reached ();
3367 for (i = 0; i < mono_array_length (params); i++) {
3368 if (sig->params [i]->byref)
3372 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3373 if (mono_error_set_pending_exception (&error))
3376 /* handle constructors only for objects already allocated */
3377 if (!strcmp (method->method->name, ".ctor"))
3378 g_assert (this_arg);
3380 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3381 g_assert (!method->method->klass->valuetype);
3382 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3383 if (mono_error_set_pending_exception (&error))
3386 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3387 if (sig->params [i]->byref) {
3389 arg = mono_array_get (params, gpointer, i);
3390 mono_array_setref (out_args, j, arg);
3395 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3402 read_enum_value (const char *mem, int type)
3405 case MONO_TYPE_BOOLEAN:
3407 return *(guint8*)mem;
3409 return *(gint8*)mem;
3410 case MONO_TYPE_CHAR:
3412 return read16 (mem);
3414 return (gint16) read16 (mem);
3416 return read32 (mem);
3418 return (gint32) read32 (mem);
3421 return read64 (mem);
3423 g_assert_not_reached ();
3429 write_enum_value (char *mem, int type, guint64 value)
3433 case MONO_TYPE_I1: {
3434 guint8 *p = (guint8*)mem;
3440 case MONO_TYPE_CHAR: {
3441 guint16 *p = (guint16 *)mem;
3446 case MONO_TYPE_I4: {
3447 guint32 *p = (guint32 *)mem;
3452 case MONO_TYPE_I8: {
3453 guint64 *p = (guint64 *)mem;
3458 g_assert_not_reached ();
3463 ICALL_EXPORT MonoObject *
3464 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3472 domain = mono_object_domain (enumType);
3473 enumc = mono_class_from_mono_type (enumType->type);
3475 mono_class_init_checked (enumc, &error);
3476 if (mono_error_set_pending_exception (&error))
3479 etype = mono_class_enum_basetype (enumc);
3481 res = mono_object_new_checked (domain, enumc, &error);
3482 if (mono_error_set_pending_exception (&error))
3484 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3489 ICALL_EXPORT MonoBoolean
3490 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3492 int size = mono_class_value_size (a->vtable->klass, NULL);
3493 guint64 a_val = 0, b_val = 0;
3495 memcpy (&a_val, mono_object_unbox (a), size);
3496 memcpy (&b_val, mono_object_unbox (b), size);
3498 return (a_val & b_val) == b_val;
3501 ICALL_EXPORT MonoObject *
3502 ves_icall_System_Enum_get_value (MonoObject *eobj)
3514 g_assert (eobj->vtable->klass->enumtype);
3516 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3517 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3518 if (mono_error_set_pending_exception (&error))
3520 dst = (char *)res + sizeof (MonoObject);
3521 src = (char *)eobj + sizeof (MonoObject);
3522 size = mono_class_value_size (enumc, NULL);
3524 memcpy (dst, src, size);
3529 ICALL_EXPORT MonoReflectionType *
3530 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3533 MonoReflectionType *ret;
3537 klass = mono_class_from_mono_type (type->type);
3538 mono_class_init_checked (klass, &error);
3539 if (mono_error_set_pending_exception (&error))
3542 etype = mono_class_enum_basetype (klass);
3544 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3548 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3549 mono_error_set_pending_exception (&error);
3555 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3557 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3558 gpointer odata = (char *)other + sizeof (MonoObject);
3559 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3560 g_assert (basetype);
3565 if (eobj->vtable->klass != other->vtable->klass)
3568 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3569 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3570 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3573 return me > other ? 1 : -1; \
3576 switch (basetype->type) {
3578 COMPARE_ENUM_VALUES (guint8);
3580 COMPARE_ENUM_VALUES (gint8);
3581 case MONO_TYPE_CHAR:
3583 COMPARE_ENUM_VALUES (guint16);
3585 COMPARE_ENUM_VALUES (gint16);
3587 COMPARE_ENUM_VALUES (guint32);
3589 COMPARE_ENUM_VALUES (gint32);
3591 COMPARE_ENUM_VALUES (guint64);
3593 COMPARE_ENUM_VALUES (gint64);
3597 #undef COMPARE_ENUM_VALUES
3598 /* indicates that the enum was of an unsupported unerlying type */
3603 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3605 gpointer data = (char *)eobj + sizeof (MonoObject);
3606 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3607 g_assert (basetype);
3609 switch (basetype->type) {
3610 case MONO_TYPE_I1: {
3611 gint8 value = *((gint8*)data);
3612 return ((int)value ^ (int)value << 8);
3615 return *((guint8*)data);
3616 case MONO_TYPE_CHAR:
3618 return *((guint16*)data);
3620 case MONO_TYPE_I2: {
3621 gint16 value = *((gint16*)data);
3622 return ((int)(guint16)value | (((int)value) << 16));
3625 return *((guint32*)data);
3627 return *((gint32*)data);
3629 case MONO_TYPE_I8: {
3630 gint64 value = *((gint64*)data);
3631 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3634 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3640 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3642 mono_error_init (error);
3643 HANDLE_FUNCTION_ENTER();
3644 guint64 field_value;
3646 MonoTypeEnum def_type;
3648 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3650 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3652 if (mono_field_is_deleted (field))
3654 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3657 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3659 p = mono_class_get_field_default_value (field, &def_type);
3660 /* len = */ mono_metadata_decode_blob_size (p, &p);
3662 field_value = read_enum_value (p, base_type);
3663 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3665 if (*previous_value > field_value)
3668 *previous_value = field_value;
3671 HANDLE_FUNCTION_RETURN();
3674 ICALL_EXPORT MonoBoolean
3675 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3677 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3678 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3679 guint j = 0, nvalues;
3681 MonoClassField *field;
3683 guint64 previous_value = 0;
3684 gboolean sorted = TRUE;
3686 mono_error_init (error);
3687 mono_class_init_checked (enumc, error);
3688 return_val_if_nok (error, FALSE);
3690 if (!enumc->enumtype) {
3691 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3695 base_type = mono_class_enum_basetype (enumc)->type;
3697 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3698 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3699 return_val_if_nok (error, FALSE);
3700 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3701 return_val_if_nok (error, FALSE);
3704 while ((field = mono_class_get_fields (enumc, &iter))) {
3705 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3709 return_val_if_nok (error, FALSE);
3715 BFLAGS_IgnoreCase = 1,
3716 BFLAGS_DeclaredOnly = 2,
3717 BFLAGS_Instance = 4,
3719 BFLAGS_Public = 0x10,
3720 BFLAGS_NonPublic = 0x20,
3721 BFLAGS_FlattenHierarchy = 0x40,
3722 BFLAGS_InvokeMethod = 0x100,
3723 BFLAGS_CreateInstance = 0x200,
3724 BFLAGS_GetField = 0x400,
3725 BFLAGS_SetField = 0x800,
3726 BFLAGS_GetProperty = 0x1000,
3727 BFLAGS_SetProperty = 0x2000,
3728 BFLAGS_ExactBinding = 0x10000,
3729 BFLAGS_SuppressChangeType = 0x20000,
3730 BFLAGS_OptionalParamBinding = 0x40000
3733 ICALL_EXPORT GPtrArray*
3734 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3737 MonoClass *startklass, *klass;
3740 int (*compare_func) (const char *s1, const char *s2) = NULL;
3741 MonoClassField *field;
3743 if (type->type->byref) {
3744 return g_ptr_array_new ();
3747 mono_error_init (&error);
3749 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3751 klass = startklass = mono_class_from_mono_type (type->type);
3753 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3756 if (mono_class_has_failure (klass)) {
3757 mono_error_set_for_class_failure (&error, klass);
3762 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3763 guint32 flags = mono_field_get_flags (field);
3765 if (mono_field_is_deleted_with_flags (field, flags))
3767 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3768 if (bflags & BFLAGS_Public)
3770 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3771 if (bflags & BFLAGS_NonPublic) {
3778 if (flags & FIELD_ATTRIBUTE_STATIC) {
3779 if (bflags & BFLAGS_Static)
3780 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3783 if (bflags & BFLAGS_Instance)
3790 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3793 g_ptr_array_add (ptr_array, field);
3795 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3801 g_ptr_array_free (ptr_array, TRUE);
3802 mono_error_set_pending_exception (&error);
3807 method_nonpublic (MonoMethod* method, gboolean start_klass)
3809 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3810 case METHOD_ATTRIBUTE_ASSEM:
3811 return (start_klass || mono_defaults.generic_ilist_class);
3812 case METHOD_ATTRIBUTE_PRIVATE:
3814 case METHOD_ATTRIBUTE_PUBLIC:
3822 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3825 MonoClass *startklass;
3829 /*FIXME, use MonoBitSet*/
3830 guint32 method_slots_default [8];
3831 guint32 *method_slots = NULL;
3832 int (*compare_func) (const char *s1, const char *s2) = NULL;
3834 array = g_ptr_array_new ();
3836 mono_error_init (error);
3839 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3841 /* An optimization for calls made from Delegate:CreateDelegate () */
3842 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3843 method = mono_get_delegate_invoke (klass);
3846 g_ptr_array_add (array, method);
3850 mono_class_setup_methods (klass);
3851 mono_class_setup_vtable (klass);
3852 if (mono_class_has_failure (klass))
3855 if (is_generic_parameter (&klass->byval_arg))
3856 nslots = mono_class_get_vtable_size (klass->parent);
3858 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3859 if (nslots >= sizeof (method_slots_default) * 8) {
3860 method_slots = g_new0 (guint32, nslots / 32 + 1);
3862 method_slots = method_slots_default;
3863 memset (method_slots, 0, sizeof (method_slots_default));
3866 mono_class_setup_methods (klass);
3867 mono_class_setup_vtable (klass);
3868 if (mono_class_has_failure (klass))
3872 while ((method = mono_class_get_methods (klass, &iter))) {
3874 if (method->slot != -1) {
3875 g_assert (method->slot < nslots);
3876 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3878 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3879 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3882 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3884 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3885 if (bflags & BFLAGS_Public)
3887 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3893 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3894 if (bflags & BFLAGS_Static)
3895 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3898 if (bflags & BFLAGS_Instance)
3906 if (compare_func (name, method->name))
3911 g_ptr_array_add (array, method);
3913 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3915 if (method_slots != method_slots_default)
3916 g_free (method_slots);
3921 if (method_slots != method_slots_default)
3922 g_free (method_slots);
3923 g_ptr_array_free (array, TRUE);
3925 g_assert (mono_class_has_failure (klass));
3926 mono_error_set_for_class_failure (error, klass);
3930 ICALL_EXPORT GPtrArray*
3931 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3934 GPtrArray *method_array;
3937 klass = mono_class_from_mono_type (type->type);
3938 if (type->type->byref) {
3939 return g_ptr_array_new ();
3942 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3943 mono_error_set_pending_exception (&error);
3944 return method_array;
3947 ICALL_EXPORT GPtrArray*
3948 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3950 MonoClass *startklass, *klass;
3953 gpointer iter = NULL;
3954 GPtrArray *res_array;
3957 if (type->type->byref) {
3958 return g_ptr_array_new ();
3961 klass = startklass = mono_class_from_mono_type (type->type);
3963 mono_class_setup_methods (klass);
3964 if (mono_class_has_failure (klass)) {
3965 mono_error_init (&error);
3966 mono_error_set_for_class_failure (&error, klass);
3967 mono_error_set_pending_exception (&error);
3971 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3974 while ((method = mono_class_get_methods (klass, &iter))) {
3976 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3978 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3979 if (bflags & BFLAGS_Public)
3982 if (bflags & BFLAGS_NonPublic)
3988 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3989 if (bflags & BFLAGS_Static)
3990 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3993 if (bflags & BFLAGS_Instance)
3999 g_ptr_array_add (res_array, method);
4006 property_hash (gconstpointer data)
4008 MonoProperty *prop = (MonoProperty*)data;
4010 return g_str_hash (prop->name);
4014 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4016 if (method1->slot != -1 && method1->slot == method2->slot)
4019 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4020 if (method1->is_inflated)
4021 method1 = ((MonoMethodInflated*) method1)->declaring;
4022 if (method2->is_inflated)
4023 method2 = ((MonoMethodInflated*) method2)->declaring;
4026 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4030 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4032 // Properties are hide-by-name-and-signature
4033 if (!g_str_equal (prop1->name, prop2->name))
4036 /* If we see a property in a generic method, we want to
4037 compare the generic signatures, not the inflated signatures
4038 because we might conflate two properties that were
4042 public T this[T t] { getter { return t; } } // method 1
4043 public U this[U u] { getter { return u; } } // method 2
4046 If we see int Foo<int,int>::Item[int] we need to know if
4047 the indexer came from method 1 or from method 2, and we
4048 shouldn't conflate them. (Bugzilla 36283)
4050 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4053 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4060 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4065 return method_nonpublic (accessor, start_klass);
4068 ICALL_EXPORT GPtrArray*
4069 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4072 MonoClass *startklass, *klass;
4077 int (*compare_func) (const char *s1, const char *s2) = NULL;
4079 GHashTable *properties = NULL;
4080 GPtrArray *res_array;
4082 if (type->type->byref) {
4083 return g_ptr_array_new ();
4086 mono_error_init (&error);
4088 klass = startklass = mono_class_from_mono_type (type->type);
4090 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4092 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4094 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4096 mono_class_setup_methods (klass);
4097 mono_class_setup_vtable (klass);
4098 if (mono_class_has_failure (klass)) {
4099 mono_error_set_for_class_failure (&error, klass);
4104 while ((prop = mono_class_get_properties (klass, &iter))) {
4110 flags = method->flags;
4113 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4114 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4115 if (bflags & BFLAGS_Public)
4117 } else if (bflags & BFLAGS_NonPublic) {
4118 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4119 property_accessor_nonpublic(prop->set, startklass == klass)) {
4126 if (flags & METHOD_ATTRIBUTE_STATIC) {
4127 if (bflags & BFLAGS_Static)
4128 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4131 if (bflags & BFLAGS_Instance)
4139 if (propname != NULL && compare_func (propname, prop->name))
4142 if (g_hash_table_lookup (properties, prop))
4145 g_ptr_array_add (res_array, prop);
4147 g_hash_table_insert (properties, prop, prop);
4149 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4152 g_hash_table_destroy (properties);
4159 g_hash_table_destroy (properties);
4160 g_ptr_array_free (res_array, TRUE);
4162 mono_error_set_pending_exception (&error);
4168 event_hash (gconstpointer data)
4170 MonoEvent *event = (MonoEvent*)data;
4172 return g_str_hash (event->name);
4176 event_equal (MonoEvent *event1, MonoEvent *event2)
4178 // Events are hide-by-name
4179 return g_str_equal (event1->name, event2->name);
4182 ICALL_EXPORT GPtrArray*
4183 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4186 MonoClass *startklass, *klass;
4191 int (*compare_func) (const char *s1, const char *s2) = NULL;
4192 GHashTable *events = NULL;
4193 GPtrArray *res_array;
4195 if (type->type->byref) {
4196 return g_ptr_array_new ();
4199 mono_error_init (&error);
4201 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4203 res_array = g_ptr_array_sized_new (4);
4205 klass = startklass = mono_class_from_mono_type (type->type);
4207 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4209 mono_class_setup_methods (klass);
4210 mono_class_setup_vtable (klass);
4211 if (mono_class_has_failure (klass)) {
4212 mono_error_set_for_class_failure (&error, klass);
4217 while ((event = mono_class_get_events (klass, &iter))) {
4219 method = event->add;
4221 method = event->remove;
4223 method = event->raise;
4225 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4226 if (bflags & BFLAGS_Public)
4228 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4229 if (bflags & BFLAGS_NonPublic)
4234 if (bflags & BFLAGS_NonPublic)
4240 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4241 if (bflags & BFLAGS_Static)
4242 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4245 if (bflags & BFLAGS_Instance)
4250 if (bflags & BFLAGS_Instance)
4255 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4258 if (g_hash_table_lookup (events, event))
4261 g_ptr_array_add (res_array, event);
4263 g_hash_table_insert (events, event, event);
4265 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4268 g_hash_table_destroy (events);
4274 g_hash_table_destroy (events);
4276 g_ptr_array_free (res_array, TRUE);
4278 mono_error_set_pending_exception (&error);
4282 ICALL_EXPORT GPtrArray *
4283 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4289 GPtrArray *res_array;
4291 if (type->type->byref) {
4292 return g_ptr_array_new ();
4295 klass = mono_class_from_mono_type (type->type);
4298 * If a nested type is generic, return its generic type definition.
4299 * Note that this means that the return value is essentially the set
4300 * of nested types of the generic type definition of @klass.
4302 * A note in MSDN claims that a generic type definition can have
4303 * nested types that aren't generic. In any case, the container of that
4304 * nested type would be the generic type definition.
4306 if (mono_class_is_ginst (klass))
4307 klass = mono_class_get_generic_class (klass)->container_class;
4309 res_array = g_ptr_array_new ();
4312 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4314 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4315 if (bflags & BFLAGS_Public)
4318 if (bflags & BFLAGS_NonPublic)
4324 if (str != NULL && strcmp (nested->name, str))
4327 g_ptr_array_add (res_array, &nested->byval_arg);
4334 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4336 HANDLE_FUNCTION_ENTER ();
4337 mono_error_init (error);
4338 MonoType *type = NULL;
4339 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4340 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4341 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4342 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4343 HANDLE_FUNCTION_RETURN_VAL (type);
4347 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4349 HANDLE_FUNCTION_ENTER ();
4350 mono_error_init (error);
4351 MonoType *type = NULL;
4352 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4353 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4354 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4355 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4356 HANDLE_FUNCTION_RETURN_VAL (type);
4359 ICALL_EXPORT MonoReflectionTypeHandle
4360 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4362 mono_error_init (error);
4364 MonoTypeNameParse info;
4365 gboolean type_resolve;
4367 /* On MS.NET, this does not fire a TypeResolve event */
4368 type_resolve = TRUE;
4369 char *str = mono_string_handle_to_utf8 (name, error);
4373 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4374 if (!mono_reflection_parse_type (str, &info)) {
4376 mono_reflection_free_type_info (&info);
4378 mono_error_set_argument (error, "name", "failed to parse the type");
4381 /*g_print ("failed parse\n");*/
4382 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4385 if (info.assembly.name) {
4387 mono_reflection_free_type_info (&info);
4389 /* 1.0 and 2.0 throw different exceptions */
4390 if (mono_defaults.generic_ilist_class)
4391 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4393 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4396 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4399 MonoType *type = NULL;
4400 if (!MONO_HANDLE_IS_NULL (module)) {
4401 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4403 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4404 if (!is_ok (error)) {
4406 mono_reflection_free_type_info (&info);
4412 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4413 if (assembly_is_dynamic (assembly)) {
4414 /* Enumerate all modules */
4415 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4416 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4419 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4420 MONO_HANDLE_GET (modules, abuilder, modules);
4421 if (!MONO_HANDLE_IS_NULL (modules)) {
4422 int n = mono_array_handle_length (modules);
4423 for (i = 0; i < n; ++i) {
4424 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4425 if (!is_ok (error)) {
4427 mono_reflection_free_type_info (&info);
4435 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4436 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4437 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4438 int n = mono_array_handle_length (loaded_modules);
4439 for (i = 0; i < n; ++i) {
4440 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4442 if (!is_ok (error)) {
4444 mono_reflection_free_type_info (&info);
4453 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4454 if (!is_ok (error)) {
4456 mono_reflection_free_type_info (&info);
4462 mono_reflection_free_type_info (&info);
4466 MonoError inner_error;
4467 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4468 mono_error_assert_ok (&inner_error);
4469 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4470 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4471 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4475 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4478 if (type->type == MONO_TYPE_CLASS) {
4479 MonoClass *klass = mono_type_get_class (type);
4481 /* need to report exceptions ? */
4482 if (throwOnError && mono_class_has_failure (klass)) {
4483 /* report SecurityException (or others) that occured when loading the assembly */
4484 mono_error_set_for_class_failure (error, klass);
4489 /* g_print ("got it\n"); */
4490 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4492 g_assert (!is_ok (error));
4493 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4497 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4500 gchar *shadow_ini_file;
4503 /* Check for shadow-copied assembly */
4504 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4505 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4507 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4508 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4514 g_free (shadow_ini_file);
4515 if (content != NULL) {
4518 *filename = content;
4525 ICALL_EXPORT MonoStringHandle
4526 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4528 mono_error_init (error);
4529 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4530 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4534 if (g_path_is_absolute (mass->image->name)) {
4535 absolute = g_strdup (mass->image->name);
4536 dirname = g_path_get_dirname (absolute);
4538 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4539 dirname = g_strdup (mass->basedir);
4542 replace_shadow_path (domain, dirname, &absolute);
4545 mono_icall_make_platform_path (absolute);
4549 uri = g_filename_to_uri (absolute, NULL, NULL);
4551 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4552 uri = g_strconcat (prepend, absolute, NULL);
4557 MonoStringHandle res;
4559 res = mono_string_new_handle (domain, uri, error);
4562 res = MONO_HANDLE_NEW (MonoString, NULL);
4567 ICALL_EXPORT MonoBoolean
4568 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4570 mono_error_init (error);
4571 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4573 return mass->in_gac;
4576 ICALL_EXPORT MonoReflectionAssemblyHandle
4577 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4580 MonoImageOpenStatus status;
4581 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4583 name = mono_string_handle_to_utf8 (mname, error);
4586 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4592 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4597 ICALL_EXPORT MonoStringHandle
4598 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4600 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4601 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4602 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4605 ICALL_EXPORT MonoBoolean
4606 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4608 mono_error_init (error);
4609 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4610 return assembly->ref_only;
4613 ICALL_EXPORT MonoStringHandle
4614 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4616 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4617 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4619 return mono_string_new_handle (domain, assembly->image->version, error);
4622 ICALL_EXPORT MonoReflectionMethodHandle
4623 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4625 mono_error_init (error);
4626 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4627 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4630 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4631 guint32 token = mono_image_get_entry_point (assembly->image);
4635 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4639 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4644 ICALL_EXPORT MonoReflectionModuleHandle
4645 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4647 mono_error_init (error);
4648 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4649 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4650 return mono_module_get_object_handle (domain, a->image, error);
4654 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4656 HANDLE_FUNCTION_ENTER ();
4657 mono_error_init (error);
4658 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4659 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4662 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4664 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4667 ICALL_EXPORT MonoArrayHandle
4668 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4670 mono_error_init (error);
4671 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4672 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4673 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4674 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4679 for (i = 0; i < table->rows; ++i) {
4680 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4685 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4688 ICALL_EXPORT MonoStringHandle
4689 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4692 guint8 aotid_sum = 0;
4693 MonoDomain* domain = mono_domain_get ();
4695 if (!domain->entry_assembly || !domain->entry_assembly->image)
4698 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4700 for (i = 0; i < 16; ++i)
4701 aotid_sum |= (*aotid)[i];
4706 gchar *guid = mono_guid_to_string((guint8*) aotid);
4707 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4712 static MonoAssemblyName*
4713 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4715 mono_error_init (error);
4716 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4718 mono_assembly_get_assemblyref (image, i, aname);
4719 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4720 /* name and culture are pointers into the image tables, but we need
4721 * real malloc'd strings (so that we can g_free() them later from
4722 * Mono.RuntimeMarshal.FreeAssemblyName) */
4723 aname->name = g_strdup (aname->name);
4724 aname->culture = g_strdup (aname->culture);
4725 /* Don't need the hash value in managed */
4726 aname->hash_value = NULL;
4727 aname->hash_len = 0;
4728 g_assert (aname->public_key == NULL);
4730 /* note: this function doesn't return the codebase on purpose (i.e. it can
4731 be used under partial trust as path information isn't present). */
4735 ICALL_EXPORT GPtrArray*
4736 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4738 mono_error_init (error);
4739 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4740 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4741 MonoImage *image = ass->image;
4743 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4744 int count = t->rows;
4746 GPtrArray *result = g_ptr_array_sized_new (count);
4748 for (int i = 0; i < count; i++) {
4749 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4752 g_ptr_array_add (result, aname);
4757 /* move this in some file in mono/util/ */
4759 g_concat_dir_and_file (const char *dir, const char *file)
4761 g_return_val_if_fail (dir != NULL, NULL);
4762 g_return_val_if_fail (file != NULL, NULL);
4765 * If the directory name doesn't have a / on the end, we need
4766 * to add one so we get a proper path to the file
4768 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4769 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4771 return g_strconcat (dir, file, NULL);
4775 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4777 mono_error_init (error);
4778 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4779 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4780 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4782 guint32 cols [MONO_MANIFEST_SIZE];
4783 guint32 impl, file_idx;
4787 char *n = mono_string_handle_to_utf8 (name, error);
4788 return_val_if_nok (error, NULL);
4790 for (i = 0; i < table->rows; ++i) {
4791 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4792 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4793 if (strcmp (val, n) == 0)
4797 if (i == table->rows)
4800 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4803 * this code should only be called after obtaining the
4804 * ResourceInfo and handling the other cases.
4806 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4807 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4809 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4810 if (!is_ok (error) || !module)
4814 module = assembly->image;
4817 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4820 MONO_HANDLE_ASSIGN (ref_module, rm);
4822 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4826 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4828 HANDLE_FUNCTION_ENTER ();
4829 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4830 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4831 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4833 guint32 cols [MONO_MANIFEST_SIZE];
4834 guint32 file_cols [MONO_FILE_SIZE];
4838 gboolean result = FALSE;
4840 n = mono_string_handle_to_utf8 (name, error);
4844 for (i = 0; i < table->rows; ++i) {
4845 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4846 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4847 if (strcmp (val, n) == 0)
4851 if (i == table->rows)
4854 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4855 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4858 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4859 case MONO_IMPLEMENTATION_FILE:
4860 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4861 table = &assembly->image->tables [MONO_TABLE_FILE];
4862 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4863 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4864 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4865 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4866 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4868 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4871 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4872 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4873 mono_assembly_load_reference (assembly->image, i - 1);
4874 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4875 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4878 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4881 MONO_HANDLE_SET (info, assembly, assm_obj);
4883 /* Obtain info recursively */
4884 get_manifest_resource_info_internal (assm_obj, name, info, error);
4887 guint32 location = MONO_HANDLE_GETVAL (info, location);
4888 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4889 MONO_HANDLE_SETVAL (info, location, guint32, location);
4892 case MONO_IMPLEMENTATION_EXP_TYPE:
4893 g_assert_not_reached ();
4900 HANDLE_FUNCTION_RETURN_VAL (result);
4903 ICALL_EXPORT gboolean
4904 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4906 mono_error_init (error);
4907 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4911 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4913 HANDLE_FUNCTION_ENTER();
4914 mono_error_init (error);
4915 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4916 char *n = g_concat_dir_and_file (assembly->basedir, val);
4917 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4921 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4923 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4926 ICALL_EXPORT MonoObjectHandle
4927 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4929 mono_error_init (error);
4930 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4931 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4932 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4935 /* check hash if needed */
4936 if (!MONO_HANDLE_IS_NULL(name)) {
4937 char *n = mono_string_handle_to_utf8 (name, error);
4941 for (i = 0; i < table->rows; ++i) {
4942 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4943 if (strcmp (val, n) == 0) {
4945 n = g_concat_dir_and_file (assembly->basedir, val);
4946 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4950 return MONO_HANDLE_CAST (MonoObject, fn);
4958 for (i = 0; i < table->rows; ++i) {
4959 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4963 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4968 for (i = 0; i < table->rows; ++i) {
4969 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4970 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4975 return MONO_HANDLE_CAST (MonoObject, result);
4981 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4983 HANDLE_FUNCTION_ENTER ();
4984 mono_error_init (error);
4986 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4990 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4995 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4999 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
5001 HANDLE_FUNCTION_ENTER ();
5002 mono_error_init (error);
5004 guint32 cols [MONO_FILE_SIZE];
5005 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
5006 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
5007 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
5010 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5012 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
5016 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
5017 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5020 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
5023 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5027 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5030 ICALL_EXPORT MonoArrayHandle
5031 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5033 mono_error_init (error);
5034 MonoDomain *domain = mono_domain_get();
5035 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5037 int i, j, file_count = 0;
5038 MonoImage **modules;
5039 guint32 module_count, real_module_count;
5040 MonoTableInfo *table;
5041 MonoImage *image = assembly->image;
5043 g_assert (image != NULL);
5044 g_assert (!assembly_is_dynamic (assembly));
5046 table = &image->tables [MONO_TABLE_FILE];
5047 file_count = table->rows;
5049 modules = image->modules;
5050 module_count = image->module_count;
5052 real_module_count = 0;
5053 for (i = 0; i < module_count; ++i)
5055 real_module_count ++;
5057 klass = mono_class_get_module_class ();
5058 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5062 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5066 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5069 for (i = 0; i < module_count; ++i)
5070 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5073 for (i = 0; i < file_count; ++i, ++j) {
5074 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5080 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5083 ICALL_EXPORT MonoReflectionMethod*
5084 ves_icall_GetCurrentMethod (void)
5086 MonoReflectionMethod *res = NULL;
5089 MonoMethod *m = mono_method_get_last_managed ();
5092 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5096 while (m->is_inflated)
5097 m = ((MonoMethodInflated*)m)->declaring;
5099 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5100 mono_error_set_pending_exception (&error);
5106 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5109 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5112 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5113 //method is inflated, we should inflate it on the other class
5114 MonoGenericContext ctx;
5115 ctx.method_inst = inflated->context.method_inst;
5116 ctx.class_inst = inflated->context.class_inst;
5117 if (mono_class_is_ginst (klass))
5118 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5119 else if (mono_class_is_gtd (klass))
5120 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5121 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5122 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5126 mono_class_setup_methods (method->klass);
5127 if (mono_class_has_failure (method->klass))
5129 int mcount = mono_class_get_method_count (method->klass);
5130 for (i = 0; i < mcount; ++i) {
5131 if (method->klass->methods [i] == method) {
5136 mono_class_setup_methods (klass);
5137 if (mono_class_has_failure (klass))
5139 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5140 return klass->methods [offset];
5143 ICALL_EXPORT MonoReflectionMethod*
5144 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5146 MonoReflectionMethod *res = NULL;
5149 if (type && generic_check) {
5150 klass = mono_class_from_mono_type (type);
5151 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5154 if (method->klass != klass) {
5155 method = mono_method_get_equivalent_method (method, klass);
5160 klass = mono_class_from_mono_type (type);
5162 klass = method->klass;
5163 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5164 mono_error_set_pending_exception (&error);
5168 ICALL_EXPORT MonoReflectionMethodBody*
5169 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5172 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5173 mono_error_set_pending_exception (&error);
5177 ICALL_EXPORT MonoReflectionAssemblyHandle
5178 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5180 mono_error_init (error);
5182 MonoMethod *dest = NULL;
5183 mono_stack_walk_no_il (get_executing, &dest);
5185 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5189 ICALL_EXPORT MonoReflectionAssemblyHandle
5190 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5192 mono_error_init (error);
5194 MonoDomain* domain = mono_domain_get ();
5196 if (!domain->entry_assembly)
5197 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5199 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5202 ICALL_EXPORT MonoReflectionAssemblyHandle
5203 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5205 mono_error_init (error);
5210 mono_stack_walk_no_il (get_executing, &dest);
5212 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5216 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5217 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5219 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5222 ICALL_EXPORT MonoStringHandle
5223 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5224 gboolean assembly_qualified, MonoError *error)
5226 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5227 MonoType *type = MONO_HANDLE_RAW (object)->type;
5228 MonoTypeNameFormat format;
5229 MonoStringHandle res;
5233 format = assembly_qualified ?
5234 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5235 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5237 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5239 name = mono_type_get_name_full (type, format);
5241 return NULL_HANDLE_STRING;
5243 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5245 return NULL_HANDLE_STRING;
5248 res = mono_string_new_handle (domain, name, error);
5255 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5258 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5260 mono_class_init_checked (klass, &error);
5261 mono_error_set_pending_exception (&error);
5262 return mono_security_core_clr_class_level (klass);
5266 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5268 MonoClassField *field = rfield->field;
5269 return mono_security_core_clr_field_level (field, TRUE);
5273 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5275 MonoMethod *method = rfield->method;
5276 return mono_security_core_clr_method_level (method, TRUE);
5279 ICALL_EXPORT MonoStringHandle
5280 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5282 mono_error_init (error);
5283 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5284 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5287 name = mono_stringify_assembly_name (&mass->aname);
5288 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5293 ICALL_EXPORT MonoAssemblyName *
5294 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5296 return &mass->aname;
5300 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5303 MonoImageOpenStatus status = MONO_IMAGE_OK;
5304 char *codebase = NULL;
5309 mono_error_init (error);
5311 filename = mono_string_handle_to_utf8 (fname, error);
5312 return_if_nok (error);
5314 dirname = g_path_get_dirname (filename);
5315 replace_shadow_path (mono_domain_get (), dirname, &filename);
5318 image = mono_image_open (filename, &status);
5321 if (status == MONO_IMAGE_IMAGE_INVALID)
5322 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5324 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5329 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5331 mono_image_close (image);
5333 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5337 if (filename != NULL && *filename != '\0') {
5340 codebase = g_strdup (filename);
5342 mono_icall_make_platform_path (codebase);
5344 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5346 result = g_strconcat (prepend, codebase, NULL);
5350 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5353 mono_image_close (image);
5357 ICALL_EXPORT MonoBoolean
5358 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5359 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5361 mono_error_init (error);
5362 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5363 MonoBoolean result = FALSE;
5364 MonoDeclSecurityEntry entry;
5366 /* SecurityAction.RequestMinimum */
5367 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5368 *minimum = entry.blob;
5369 *minLength = entry.size;
5372 /* SecurityAction.RequestOptional */
5373 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5374 *optional = entry.blob;
5375 *optLength = entry.size;
5378 /* SecurityAction.RequestRefuse */
5379 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5380 *refused = entry.blob;
5381 *refLength = entry.size;
5389 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5391 guint32 attrs, visibility;
5393 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5394 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5395 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5398 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5404 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5406 mono_error_init (error);
5407 HANDLE_FUNCTION_ENTER ();
5408 MonoError klass_error;
5409 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5412 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5413 return_if_nok (error);
5415 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5417 MonoException *ex = mono_error_convert_to_exception (error);
5418 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5420 HANDLE_FUNCTION_RETURN ();
5423 static MonoArrayHandle
5424 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5426 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5429 mono_error_init (error);
5431 /* we start the count from 1 because we skip the special type <Module> */
5434 for (i = 1; i < tdef->rows; ++i) {
5435 if (mono_module_type_is_visible (tdef, image, i + 1))
5439 count = tdef->rows - 1;
5441 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5442 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5443 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5444 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5446 for (i = 1; i < tdef->rows; ++i) {
5447 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5448 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5449 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5458 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5460 HANDLE_FUNCTION_ENTER ();
5461 mono_error_init (error);
5462 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5463 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5467 /* Append the new types to the end of the array */
5468 if (mono_array_handle_length (res2) > 0) {
5471 len1 = mono_array_handle_length (res);
5472 len2 = mono_array_handle_length (res2);
5474 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5478 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5479 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5480 MONO_HANDLE_ASSIGN (res, res3);
5482 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5486 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5487 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5488 MONO_HANDLE_ASSIGN (exceptions, ex3);
5491 HANDLE_FUNCTION_RETURN ();
5495 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5497 HANDLE_FUNCTION_ENTER ();
5498 MonoError unboxed_error;
5499 mono_error_init (&unboxed_error);
5500 mono_error_set_for_class_failure (&unboxed_error, klass);
5502 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5503 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5504 HANDLE_FUNCTION_RETURN ();
5507 ICALL_EXPORT MonoArrayHandle
5508 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5510 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5513 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5514 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5516 g_assert (!assembly_is_dynamic (assembly));
5517 MonoImage *image = assembly->image;
5518 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5519 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5520 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5522 /* Append data from all modules in the assembly */
5523 for (i = 0; i < table->rows; ++i) {
5524 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5525 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5526 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5529 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5530 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5535 /* the ReflectionTypeLoadException must have all the types (Types property),
5536 * NULL replacing types which throws an exception. The LoaderException must
5537 * contain all exceptions for NULL items.
5540 int len = mono_array_handle_length (res);
5544 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5545 for (i = 0; i < len; i++) {
5546 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5548 if (!MONO_HANDLE_IS_NULL (t)) {
5549 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5550 if ((klass != NULL) && mono_class_has_failure (klass)) {
5551 /* keep the class in the list */
5552 list = g_list_append (list, klass);
5553 /* and replace Type with NULL */
5554 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5561 if (list || ex_count) {
5563 int j, length = g_list_length (list) + ex_count;
5565 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5566 if (!is_ok (error)) {
5568 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5570 /* Types for which mono_class_get_checked () succeeded */
5571 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5572 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5573 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5575 /* Types for which it don't */
5576 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5577 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5578 if (!MONO_HANDLE_IS_NULL (exc)) {
5579 g_assert (i < length);
5580 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5587 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5588 if (!is_ok (error)) {
5589 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5591 mono_error_set_exception_handle (error, exc);
5592 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5599 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5601 mono_assembly_name_free (aname);
5606 ICALL_EXPORT gboolean
5607 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5609 *is_version_definited = *is_token_defined = FALSE;
5611 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5614 ICALL_EXPORT MonoReflectionTypeHandle
5615 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5617 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5618 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5623 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5625 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5626 /* These images do not have a global type */
5629 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5633 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5639 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5641 /*if (module->image)
5642 mono_image_close (module->image);*/
5645 ICALL_EXPORT MonoStringHandle
5646 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5648 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5649 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5652 return mono_string_new_handle (domain, image->guid, error);
5656 static inline gpointer
5657 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5659 return (gpointer) (-1);
5661 #endif /* HOST_WIN32 */
5663 ICALL_EXPORT gpointer
5664 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5666 return mono_icall_module_get_hinstance (module);
5670 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5672 if (image_is_dynamic (image)) {
5673 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5674 *pe_kind = dyn->pe_kind;
5675 *machine = dyn->machine;
5678 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5679 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5684 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5686 return (image->md_version_major << 16) | (image->md_version_minor);
5689 ICALL_EXPORT MonoArrayHandle
5690 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5692 mono_error_init (error);
5694 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5695 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5698 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5701 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5702 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5703 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5705 int n = mono_array_handle_length (exceptions);
5706 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5707 for (int i = 0; i < n; ++i) {
5708 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5709 if (!MONO_HANDLE_IS_NULL (ex)) {
5710 mono_error_set_exception_handle (error, ex);
5711 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5719 mono_memberref_is_method (MonoImage *image, guint32 token)
5721 if (!image_is_dynamic (image)) {
5722 guint32 cols [MONO_MEMBERREF_SIZE];
5724 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5725 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5726 mono_metadata_decode_blob_size (sig, &sig);
5727 return (*sig != 0x6);
5730 MonoClass *handle_class;
5732 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5733 mono_error_cleanup (&error); /* just probing, ignore error */
5737 return mono_defaults.methodhandle_class == handle_class;
5742 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5745 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5746 mono_array_addr (type_args, MonoType*, 0));
5748 context->class_inst = NULL;
5750 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5751 mono_array_addr (method_args, MonoType*, 0));
5753 context->method_inst = NULL;
5756 ICALL_EXPORT MonoType*
5757 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5760 int table = mono_metadata_token_table (token);
5761 int index = mono_metadata_token_index (token);
5762 MonoGenericContext context;
5765 *resolve_error = ResolveTokenError_Other;
5767 /* Validate token */
5768 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5769 (table != MONO_TABLE_TYPESPEC)) {
5770 *resolve_error = ResolveTokenError_BadTable;
5774 if (image_is_dynamic (image)) {
5775 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5776 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5777 mono_error_cleanup (&error);
5778 return klass ? &klass->byval_arg : NULL;
5781 init_generic_context_from_args (&context, type_args, method_args);
5782 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5783 mono_error_cleanup (&error);
5784 return klass ? &klass->byval_arg : NULL;
5787 if ((index <= 0) || (index > image->tables [table].rows)) {
5788 *resolve_error = ResolveTokenError_OutOfRange;
5792 init_generic_context_from_args (&context, type_args, method_args);
5793 klass = mono_class_get_checked (image, token, &error);
5795 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5796 if (!mono_error_ok (&error)) {
5797 mono_error_set_pending_exception (&error);
5802 return &klass->byval_arg;
5807 ICALL_EXPORT MonoMethod*
5808 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5811 int table = mono_metadata_token_table (token);
5812 int index = mono_metadata_token_index (token);
5813 MonoGenericContext context;
5816 *resolve_error = ResolveTokenError_Other;
5818 /* Validate token */
5819 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5820 (table != MONO_TABLE_MEMBERREF)) {
5821 *resolve_error = ResolveTokenError_BadTable;
5825 if (image_is_dynamic (image)) {
5826 if (table == MONO_TABLE_METHOD) {
5827 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5828 mono_error_cleanup (&error);
5832 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5833 *resolve_error = ResolveTokenError_BadTable;
5837 init_generic_context_from_args (&context, type_args, method_args);
5838 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5839 mono_error_cleanup (&error);
5843 if ((index <= 0) || (index > image->tables [table].rows)) {
5844 *resolve_error = ResolveTokenError_OutOfRange;
5847 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5848 *resolve_error = ResolveTokenError_BadTable;
5852 init_generic_context_from_args (&context, type_args, method_args);
5853 method = mono_get_method_checked (image, token, NULL, &context, &error);
5854 mono_error_set_pending_exception (&error);
5859 ICALL_EXPORT MonoString*
5860 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5863 int index = mono_metadata_token_index (token);
5865 *resolve_error = ResolveTokenError_Other;
5867 /* Validate token */
5868 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5869 *resolve_error = ResolveTokenError_BadTable;
5873 if (image_is_dynamic (image)) {
5874 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5875 mono_error_cleanup (&error);
5879 if ((index <= 0) || (index >= image->heap_us.size)) {
5880 *resolve_error = ResolveTokenError_OutOfRange;
5884 /* FIXME: What to do if the index points into the middle of a string ? */
5886 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5887 mono_error_set_pending_exception (&error);
5891 ICALL_EXPORT MonoClassField*
5892 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5896 int table = mono_metadata_token_table (token);
5897 int index = mono_metadata_token_index (token);
5898 MonoGenericContext context;
5899 MonoClassField *field;
5901 *resolve_error = ResolveTokenError_Other;
5903 /* Validate token */
5904 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5905 *resolve_error = ResolveTokenError_BadTable;
5909 if (image_is_dynamic (image)) {
5910 if (table == MONO_TABLE_FIELD) {
5911 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5912 mono_error_cleanup (&error);
5916 if (mono_memberref_is_method (image, token)) {
5917 *resolve_error = ResolveTokenError_BadTable;
5921 init_generic_context_from_args (&context, type_args, method_args);
5922 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5923 mono_error_cleanup (&error);
5927 if ((index <= 0) || (index > image->tables [table].rows)) {
5928 *resolve_error = ResolveTokenError_OutOfRange;
5931 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5932 *resolve_error = ResolveTokenError_BadTable;
5936 init_generic_context_from_args (&context, type_args, method_args);
5937 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5938 mono_error_set_pending_exception (&error);
5944 ICALL_EXPORT MonoObject*
5945 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5949 int table = mono_metadata_token_table (token);
5951 *error = ResolveTokenError_Other;
5954 case MONO_TABLE_TYPEDEF:
5955 case MONO_TABLE_TYPEREF:
5956 case MONO_TABLE_TYPESPEC: {
5957 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5959 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5960 mono_error_set_pending_exception (&merror);
5967 case MONO_TABLE_METHOD:
5968 case MONO_TABLE_METHODSPEC: {
5969 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5971 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5972 mono_error_set_pending_exception (&merror);
5978 case MONO_TABLE_FIELD: {
5979 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5981 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5982 mono_error_set_pending_exception (&merror);
5988 case MONO_TABLE_MEMBERREF:
5989 if (mono_memberref_is_method (image, token)) {
5990 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5992 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5993 mono_error_set_pending_exception (&merror);
6000 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6002 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6003 mono_error_set_pending_exception (&merror);
6012 *error = ResolveTokenError_BadTable;
6018 ICALL_EXPORT MonoArray*
6019 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6022 int table = mono_metadata_token_table (token);
6023 int idx = mono_metadata_token_index (token);
6024 MonoTableInfo *tables = image->tables;
6029 *resolve_error = ResolveTokenError_OutOfRange;
6031 /* FIXME: Support other tables ? */
6032 if (table != MONO_TABLE_STANDALONESIG)
6035 if (image_is_dynamic (image))
6038 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6041 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6043 ptr = mono_metadata_blob_heap (image, sig);
6044 len = mono_metadata_decode_blob_size (ptr, &ptr);
6046 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6047 if (mono_error_set_pending_exception (&error))
6049 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6053 ICALL_EXPORT MonoBoolean
6054 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6060 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6066 check_for_invalid_type (MonoClass *klass, MonoError *error)
6070 mono_error_init (error);
6072 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6075 name = mono_type_get_full_name (klass);
6076 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6078 ICALL_EXPORT MonoReflectionType *
6079 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6082 MonoReflectionType *ret;
6083 MonoClass *klass, *aklass;
6085 klass = mono_class_from_mono_type (type->type);
6086 check_for_invalid_type (klass, &error);
6087 if (mono_error_set_pending_exception (&error))
6090 if (rank == 0) //single dimentional array
6091 aklass = mono_array_class_get (klass, 1);
6093 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6095 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6096 mono_error_set_pending_exception (&error);
6101 ICALL_EXPORT MonoReflectionType *
6102 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6105 MonoReflectionType *ret;
6108 klass = mono_class_from_mono_type (type->type);
6109 mono_class_init_checked (klass, &error);
6110 if (mono_error_set_pending_exception (&error))
6113 check_for_invalid_type (klass, &error);
6114 if (mono_error_set_pending_exception (&error))
6117 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6118 mono_error_set_pending_exception (&error);
6123 ICALL_EXPORT MonoReflectionType *
6124 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6127 MonoReflectionType *ret;
6128 MonoClass *klass, *pklass;
6130 klass = mono_class_from_mono_type (type->type);
6131 mono_class_init_checked (klass, &error);
6132 if (mono_error_set_pending_exception (&error))
6134 check_for_invalid_type (klass, &error);
6135 if (mono_error_set_pending_exception (&error))
6138 pklass = mono_ptr_class_get (type->type);
6140 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6141 mono_error_set_pending_exception (&error);
6146 ICALL_EXPORT MonoObject *
6147 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6148 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6151 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6152 MonoObject *delegate;
6154 MonoMethod *method = info->method;
6155 MonoMethodSignature *sig = mono_method_signature(method);
6157 mono_class_init_checked (delegate_class, &error);
6158 if (mono_error_set_pending_exception (&error))
6161 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6162 /* FIXME improve this exception message */
6163 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6165 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6166 mono_error_set_pending_exception (&error);
6170 if (mono_security_core_clr_enabled ()) {
6171 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6172 if (throwOnBindFailure)
6173 mono_error_set_pending_exception (&error);
6175 mono_error_cleanup (&error);
6180 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6181 if (!method->is_inflated) {
6182 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"));
6187 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6188 if (mono_error_set_pending_exception (&error))
6191 if (method_is_dynamic (method)) {
6192 /* Creating a trampoline would leak memory */
6193 func = mono_compile_method_checked (method, &error);
6194 if (mono_error_set_pending_exception (&error))
6197 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6198 method = mono_object_get_virtual_method (target, method);
6199 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6200 if (mono_error_set_pending_exception (&error))
6202 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6205 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6206 if (mono_error_set_pending_exception (&error))
6211 ICALL_EXPORT MonoMulticastDelegate *
6212 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6215 MonoMulticastDelegate *ret;
6217 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6219 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6220 if (mono_error_set_pending_exception (&error))
6223 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6228 ICALL_EXPORT MonoReflectionMethod*
6229 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6231 MonoReflectionMethod *ret = NULL;
6233 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6234 mono_error_set_pending_exception (&error);
6240 static inline gint32
6241 mono_array_get_byte_length (MonoArray *array)
6247 klass = array->obj.vtable->klass;
6249 if (array->bounds == NULL)
6250 length = array->max_length;
6253 for (i = 0; i < klass->rank; ++ i)
6254 length *= array->bounds [i].length;
6257 switch (klass->element_class->byval_arg.type) {
6260 case MONO_TYPE_BOOLEAN:
6264 case MONO_TYPE_CHAR:
6272 return length * sizeof (gpointer);
6283 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6285 return mono_array_get_byte_length (array);
6289 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6291 return mono_array_get (array, gint8, idx);
6295 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6297 mono_array_set (array, gint8, idx, value);
6300 ICALL_EXPORT MonoBoolean
6301 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6303 guint8 *src_buf, *dest_buf;
6306 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6310 g_assert (count >= 0);
6312 /* This is called directly from the class libraries without going through the managed wrapper */
6313 MONO_CHECK_ARG_NULL (src, FALSE);
6314 MONO_CHECK_ARG_NULL (dest, FALSE);
6316 /* watch out for integer overflow */
6317 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6320 src_buf = (guint8 *)src->vector + src_offset;
6321 dest_buf = (guint8 *)dest->vector + dest_offset;
6324 memcpy (dest_buf, src_buf, count);
6326 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6331 #ifndef DISABLE_REMOTING
6332 ICALL_EXPORT MonoObject *
6333 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6336 MonoDomain *domain = mono_object_domain (this_obj);
6338 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6339 MonoTransparentProxy *tp;
6343 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6344 if (mono_error_set_pending_exception (&error))
6347 tp = (MonoTransparentProxy*) res;
6349 MONO_OBJECT_SETREF (tp, rp, rp);
6350 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6351 klass = mono_class_from_mono_type (type);
6353 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6354 mono_class_setup_vtable (klass);
6355 if (mono_class_has_failure (klass)) {
6356 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6360 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6361 if (mono_error_set_pending_exception (&error))
6363 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6364 if (mono_error_set_pending_exception (&error))
6367 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6368 if (mono_error_set_pending_exception (&error))
6373 ICALL_EXPORT MonoReflectionType *
6374 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6377 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6378 mono_error_set_pending_exception (&error);
6384 /* System.Environment */
6387 ves_icall_System_Environment_get_UserName (void)
6389 /* using glib is more portable */
6390 return mono_string_new (mono_domain_get (), g_get_user_name ());
6395 mono_icall_get_machine_name (void)
6397 #if !defined(DISABLE_SOCKETS)
6401 #if defined _SC_HOST_NAME_MAX
6402 n = sysconf (_SC_HOST_NAME_MAX);
6406 buf = g_malloc (n+1);
6408 if (gethostname (buf, n) == 0){
6410 result = mono_string_new (mono_domain_get (), buf);
6417 return mono_string_new (mono_domain_get (), "mono");
6420 #endif /* !HOST_WIN32 */
6422 ICALL_EXPORT MonoString *
6423 ves_icall_System_Environment_get_MachineName (void)
6425 return mono_icall_get_machine_name ();
6430 mono_icall_get_platform (void)
6432 #if defined(__MACH__)
6435 // Notice that the value is hidden from user code, and only exposed
6436 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6437 // define and making assumptions based on Unix/128/4 values before there
6438 // was a MacOS define. Lots of code would assume that not-Unix meant
6439 // Windows, but in this case, it would be OSX.
6447 #endif /* !HOST_WIN32 */
6450 ves_icall_System_Environment_get_Platform (void)
6452 return mono_icall_get_platform ();
6456 static inline MonoString *
6457 mono_icall_get_new_line (void)
6459 return mono_string_new (mono_domain_get (), "\n");
6461 #endif /* !HOST_WIN32 */
6463 ICALL_EXPORT MonoString *
6464 ves_icall_System_Environment_get_NewLine (void)
6466 return mono_icall_get_new_line ();
6470 static inline MonoBoolean
6471 mono_icall_is_64bit_os (void)
6473 #if SIZEOF_VOID_P == 8
6476 #if defined(HAVE_SYS_UTSNAME_H)
6477 struct utsname name;
6479 if (uname (&name) >= 0) {
6480 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6486 #endif /* !HOST_WIN32 */
6488 ICALL_EXPORT MonoBoolean
6489 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6491 return mono_icall_is_64bit_os ();
6494 ICALL_EXPORT MonoStringHandle
6495 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6499 if (utf8_name == NULL)
6500 return NULL_HANDLE_STRING;
6502 value = g_getenv (utf8_name);
6505 return NULL_HANDLE_STRING;
6507 return mono_string_new_handle (mono_domain_get (), value, error);
6511 * There is no standard way to get at environ.
6514 #ifndef __MINGW32_VERSION
6515 #if defined(__APPLE__)
6516 #if defined (TARGET_OSX)
6517 /* Apple defines this in crt_externs.h but doesn't provide that header for
6518 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6519 * in fact exist on all implementations (so far)
6521 gchar ***_NSGetEnviron(void);
6522 #define environ (*_NSGetEnviron())
6524 static char *mono_environ[1] = { NULL };
6525 #define environ mono_environ
6526 #endif /* defined (TARGET_OSX) */
6534 ICALL_EXPORT MonoArray *
6535 ves_icall_System_Environment_GetCoomandLineArgs (void)
6538 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6539 mono_error_set_pending_exception (&error);
6545 mono_icall_get_environment_variable_names (void)
6555 for (e = environ; *e != 0; ++ e)
6558 domain = mono_domain_get ();
6559 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6560 if (mono_error_set_pending_exception (&error))
6564 for (e = environ; *e != 0; ++ e) {
6565 parts = g_strsplit (*e, "=", 2);
6567 str = mono_string_new (domain, *parts);
6568 mono_array_setref (names, n, str);
6578 #endif /* !HOST_WIN32 */
6580 ICALL_EXPORT MonoArray *
6581 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6583 return mono_icall_get_environment_variable_names ();
6588 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6590 gchar *utf8_name, *utf8_value;
6593 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6594 if (mono_error_set_pending_exception (&error))
6597 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6598 g_unsetenv (utf8_name);
6603 utf8_value = mono_string_to_utf8_checked (value, &error);
6604 if (!mono_error_ok (&error)) {
6606 mono_error_set_pending_exception (&error);
6609 g_setenv (utf8_name, utf8_value, TRUE);
6612 g_free (utf8_value);
6614 #endif /* !HOST_WIN32 */
6617 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6619 mono_icall_set_environment_variable (name, value);
6623 ves_icall_System_Environment_Exit (int result)
6625 mono_environment_exitcode_set (result);
6627 /* FIXME: There are some cleanup hangs that should be worked out, but
6628 * if the program is going to exit, everything will be cleaned up when
6629 * NaCl exits anyway.
6631 #ifndef __native_client__
6632 if (!mono_runtime_try_shutdown ())
6633 mono_thread_exit ();
6635 /* Suspend all managed threads since the runtime is going away */
6636 mono_thread_suspend_all_other_threads ();
6638 mono_runtime_quit ();
6641 /* we may need to do some cleanup here... */
6645 ICALL_EXPORT MonoStringHandle
6646 ves_icall_System_Environment_GetGacPath (MonoError *error)
6648 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6652 static inline MonoString *
6653 mono_icall_get_windows_folder_path (int folder)
6655 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6656 return mono_string_new (mono_domain_get (), "");
6658 #endif /* !HOST_WIN32 */
6660 ICALL_EXPORT MonoString*
6661 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6663 return mono_icall_get_windows_folder_path (folder);
6666 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6668 mono_icall_get_logical_drives (void)
6671 gunichar2 buf [256], *ptr, *dname;
6673 guint initial_size = 127, size = 128;
6676 MonoString *drivestr;
6677 MonoDomain *domain = mono_domain_get ();
6683 while (size > initial_size) {
6684 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6685 if (size > initial_size) {
6688 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6689 initial_size = size;
6703 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6704 if (mono_error_set_pending_exception (&error))
6711 while (*u16) { u16++; len ++; }
6712 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6713 if (mono_error_set_pending_exception (&error))
6716 mono_array_setref (result, ndrives++, drivestr);
6726 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6728 ICALL_EXPORT MonoArray *
6729 ves_icall_System_Environment_GetLogicalDrives (void)
6731 return mono_icall_get_logical_drives ();
6734 ICALL_EXPORT MonoString *
6735 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6738 gunichar2 volume_name [MAX_PATH + 1];
6740 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6742 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6743 mono_error_set_pending_exception (&error);
6747 ICALL_EXPORT MonoStringHandle
6748 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6750 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6753 static const char *encodings [] = {
6755 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6756 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6757 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6759 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6760 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6761 "x_unicode_2_0_utf_7",
6763 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6764 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6766 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6769 "unicodefffe", "utf_16be",
6776 * Returns the internal codepage, if the value of "int_code_page" is
6777 * 1 at entry, and we can not compute a suitable code page number,
6778 * returns the code page as a string
6780 ICALL_EXPORT MonoString*
6781 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6786 char *codepage = NULL;
6788 int want_name = *int_code_page;
6791 *int_code_page = -1;
6793 g_get_charset (&cset);
6794 c = codepage = g_strdup (cset);
6795 for (c = codepage; *c; c++){
6796 if (isascii (*c) && isalpha (*c))
6801 /* g_print ("charset: %s\n", cset); */
6803 /* handle some common aliases */
6806 for (i = 0; p != 0; ){
6809 p = encodings [++i];
6812 if (strcmp (p, codepage) == 0){
6813 *int_code_page = code;
6816 p = encodings [++i];
6819 if (strstr (codepage, "utf_8") != NULL)
6820 *int_code_page |= 0x10000000;
6823 if (want_name && *int_code_page == -1)
6824 return mono_string_new (mono_domain_get (), cset);
6829 ICALL_EXPORT MonoBoolean
6830 ves_icall_System_Environment_get_HasShutdownStarted (void)
6832 if (mono_runtime_is_shutting_down ())
6835 if (mono_domain_is_unloading (mono_domain_get ()))
6843 mono_icall_broadcast_setting_change (void)
6847 #endif /* !HOST_WIN32 */
6850 ves_icall_System_Environment_BroadcastSettingChange (void)
6852 mono_icall_broadcast_setting_change ();
6857 ves_icall_System_Environment_get_TickCount (void)
6859 /* this will overflow after ~24 days */
6860 return (gint32) (mono_msec_boottime () & 0xffffffff);
6864 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6869 #ifndef DISABLE_REMOTING
6870 ICALL_EXPORT MonoBoolean
6871 ves_icall_IsTransparentProxy (MonoObject *proxy)
6876 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6882 ICALL_EXPORT MonoReflectionMethod *
6883 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6884 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6886 MonoReflectionMethod *ret = NULL;
6891 MonoMethod **vtable;
6892 MonoMethod *res = NULL;
6894 MONO_CHECK_ARG_NULL (rtype, NULL);
6895 MONO_CHECK_ARG_NULL (rmethod, NULL);
6897 method = rmethod->method;
6898 klass = mono_class_from_mono_type (rtype->type);
6899 mono_class_init_checked (klass, &error);
6900 if (mono_error_set_pending_exception (&error))
6903 if (MONO_CLASS_IS_INTERFACE (klass))
6906 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6909 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6910 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6916 mono_class_setup_vtable (klass);
6917 vtable = klass->vtable;
6919 if (mono_class_is_interface (method->klass)) {
6920 gboolean variance_used = FALSE;
6921 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6922 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6924 res = vtable [offs + method->slot];
6926 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6929 if (method->slot != -1)
6930 res = vtable [method->slot];
6936 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6937 mono_error_set_pending_exception (&error);
6942 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6948 klass = mono_class_from_mono_type (type->type);
6949 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6950 if (!is_ok (&error)) {
6951 mono_error_set_pending_exception (&error);
6955 mono_vtable_set_is_remote (vtable, enable);
6958 #else /* DISABLE_REMOTING */
6961 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6963 g_assert_not_reached ();
6968 ICALL_EXPORT MonoObject *
6969 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6976 domain = mono_object_domain (type);
6977 klass = mono_class_from_mono_type (type->type);
6978 mono_class_init_checked (klass, &error);
6979 if (mono_error_set_pending_exception (&error))
6982 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6983 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6987 if (klass->rank >= 1) {
6988 g_assert (klass->rank == 1);
6989 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6990 mono_error_set_pending_exception (&error);
6993 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6994 if (!is_ok (&error)) {
6995 mono_error_set_pending_exception (&error);
6998 /* Bypass remoting object creation check */
6999 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7000 mono_error_set_pending_exception (&error);
7006 ICALL_EXPORT MonoStringHandle
7007 ves_icall_System_IO_get_temp_path (MonoError *error)
7009 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7012 #ifndef PLATFORM_NO_DRIVEINFO
7013 ICALL_EXPORT MonoBoolean
7014 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7015 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7019 ULARGE_INTEGER wapi_free_bytes_avail;
7020 ULARGE_INTEGER wapi_total_number_of_bytes;
7021 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7023 *error = ERROR_SUCCESS;
7024 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7025 &wapi_total_number_of_free_bytes);
7028 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7029 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7030 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7032 *free_bytes_avail = 0;
7033 *total_number_of_bytes = 0;
7034 *total_number_of_free_bytes = 0;
7035 *error = GetLastError ();
7041 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7042 static inline guint32
7043 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7045 return GetDriveType (mono_string_chars (root_path_name));
7047 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7049 ICALL_EXPORT guint32
7050 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7052 return mono_icall_drive_info_get_drive_type (root_path_name);
7055 #endif /* PLATFORM_NO_DRIVEINFO */
7057 ICALL_EXPORT gpointer
7058 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7061 gpointer result = mono_compile_method_checked (method, &error);
7062 mono_error_set_pending_exception (&error);
7066 ICALL_EXPORT MonoString *
7067 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7072 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7074 mono_icall_make_platform_path (path);
7076 mcpath = mono_string_new (mono_domain_get (), path);
7082 /* this is an icall */
7084 get_bundled_app_config (void)
7087 const gchar *app_config;
7090 gchar *config_file_name, *config_file_path;
7091 gsize len, config_file_path_length, config_ext_length;
7094 domain = mono_domain_get ();
7095 file = domain->setup->configuration_file;
7096 if (!file || file->length == 0)
7099 // Retrieve config file and remove the extension
7100 config_file_name = mono_string_to_utf8_checked (file, &error);
7101 if (mono_error_set_pending_exception (&error))
7103 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7104 if (!config_file_path)
7105 config_file_path = config_file_name;
7107 config_file_path_length = strlen (config_file_path);
7108 config_ext_length = strlen (".config");
7109 if (config_file_path_length <= config_ext_length)
7112 len = config_file_path_length - config_ext_length;
7113 module = (gchar *)g_malloc0 (len + 1);
7114 memcpy (module, config_file_path, len);
7115 // Get the config file from the module name
7116 app_config = mono_config_string_for_assembly_file (module);
7119 if (config_file_name != config_file_path)
7120 g_free (config_file_name);
7121 g_free (config_file_path);
7126 return mono_string_new (mono_domain_get (), app_config);
7129 static MonoStringHandle
7130 get_bundled_machine_config (MonoError *error)
7132 const gchar *machine_config;
7134 machine_config = mono_get_machine_config ();
7136 if (!machine_config)
7137 return NULL_HANDLE_STRING;
7139 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7142 ICALL_EXPORT MonoStringHandle
7143 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7145 return get_bundled_machine_config (error);
7149 ICALL_EXPORT MonoStringHandle
7150 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7152 return get_bundled_machine_config (error);
7155 ICALL_EXPORT MonoStringHandle
7156 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7158 return get_bundled_machine_config (error);
7162 ICALL_EXPORT MonoString *
7163 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7168 path = g_path_get_dirname (mono_get_config_dir ());
7170 mono_icall_make_platform_path (path);
7172 ipath = mono_string_new (mono_domain_get (), path);
7178 ICALL_EXPORT gboolean
7179 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7181 mono_error_init (error);
7182 MonoPEResourceDataEntry *entry;
7185 if (!assembly || !result || !size)
7190 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7191 image = assm->image;
7192 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7196 *result = mono_image_rva_map (image, entry->rde_data_offset);
7201 *size = entry->rde_size;
7206 ICALL_EXPORT MonoBoolean
7207 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7209 return mono_is_debugger_attached ();
7212 ICALL_EXPORT MonoBoolean
7213 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7215 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7216 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7222 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7224 if (mono_get_runtime_callbacks ()->debug_log)
7225 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7230 mono_icall_write_windows_debug_string (MonoString *message)
7232 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7234 #endif /* !HOST_WIN32 */
7237 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7239 mono_icall_write_windows_debug_string (message);
7242 /* Only used for value types */
7243 ICALL_EXPORT MonoObject *
7244 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7251 domain = mono_object_domain (type);
7252 klass = mono_class_from_mono_type (type->type);
7253 mono_class_init_checked (klass, &error);
7254 if (mono_error_set_pending_exception (&error))
7257 if (mono_class_is_nullable (klass))
7258 /* No arguments -> null */
7261 result = mono_object_new_checked (domain, klass, &error);
7262 mono_error_set_pending_exception (&error);
7266 ICALL_EXPORT MonoReflectionMethod *
7267 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7269 MonoReflectionMethod *ret = NULL;
7272 MonoClass *klass, *parent;
7273 MonoGenericContext *generic_inst = NULL;
7274 MonoMethod *method = m->method;
7275 MonoMethod *result = NULL;
7278 if (method->klass == NULL)
7281 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7282 MONO_CLASS_IS_INTERFACE (method->klass) ||
7283 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7286 slot = mono_method_get_vtable_slot (method);
7290 klass = method->klass;
7291 if (mono_class_is_ginst (klass)) {
7292 generic_inst = mono_class_get_context (klass);
7293 klass = mono_class_get_generic_class (klass)->container_class;
7298 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7299 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7300 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7301 or klass is the generic container class and generic_inst is the instantiation.
7303 when we go to the parent, if the parent is an open constructed type, we need to
7304 replace the type parameters by the definitions from the generic_inst, and then take it
7305 apart again into the klass and the generic_inst.
7307 For cases like this:
7308 class C<T> : B<T, int> {
7309 public override void Foo () { ... }
7311 class B<U,V> : A<HashMap<U,V>> {
7312 public override void Foo () { ... }
7315 public virtual void Foo () { ... }
7318 if at each iteration the parent isn't open, we can skip inflating it. if at some
7319 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7322 MonoGenericContext *parent_inst = NULL;
7323 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7324 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7325 if (!mono_error_ok (&error)) {
7326 mono_error_set_pending_exception (&error);
7330 if (mono_class_is_ginst (parent)) {
7331 parent_inst = mono_class_get_context (parent);
7332 parent = mono_class_get_generic_class (parent)->container_class;
7335 mono_class_setup_vtable (parent);
7336 if (parent->vtable_size <= slot)
7339 generic_inst = parent_inst;
7342 klass = klass->parent;
7345 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7346 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7347 if (!mono_error_ok (&error)) {
7348 mono_error_set_pending_exception (&error);
7352 generic_inst = NULL;
7354 if (mono_class_is_ginst (klass)) {
7355 generic_inst = mono_class_get_context (klass);
7356 klass = mono_class_get_generic_class (klass)->container_class;
7362 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7363 if (!mono_error_ok (&error)) {
7364 mono_error_set_pending_exception (&error);
7369 if (klass == method->klass)
7372 /*This is possible if definition == FALSE.
7373 * Do it here to be really sure we don't read invalid memory.
7375 if (slot >= klass->vtable_size)
7378 mono_class_setup_vtable (klass);
7380 result = klass->vtable [slot];
7381 if (result == NULL) {
7382 /* It is an abstract method */
7383 gboolean found = FALSE;
7384 gpointer iter = NULL;
7385 while ((result = mono_class_get_methods (klass, &iter))) {
7386 if (result->slot == slot) {
7391 /* found might be FALSE if we looked in an abstract class
7392 * that doesn't override an abstract method of its
7394 * abstract class Base {
7395 * public abstract void Foo ();
7397 * abstract class Derived : Base { }
7398 * class Child : Derived {
7399 * public override void Foo () { }
7402 * if m was Child.Foo and we ask for the base method,
7403 * then we get here with klass == Derived and found == FALSE
7405 /* but it shouldn't be the case that if we're looking
7406 * for the definition and didn't find a result; the
7407 * loop above should've taken us as far as we could
7409 g_assert (!(definition && !found));
7414 g_assert (result != NULL);
7416 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7417 mono_error_set_pending_exception (&error);
7421 ICALL_EXPORT MonoString*
7422 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7424 MonoMethod *method = m->method;
7426 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7431 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7433 iter->sig = *(MonoMethodSignature**)argsp;
7435 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7436 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7439 /* FIXME: it's not documented what start is exactly... */
7443 iter->args = argsp + sizeof (gpointer);
7445 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7447 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7450 ICALL_EXPORT MonoTypedRef
7451 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7453 guint32 i, arg_size;
7457 i = iter->sig->sentinelpos + iter->next_arg;
7459 g_assert (i < iter->sig->param_count);
7461 res.type = iter->sig->params [i];
7462 res.klass = mono_class_from_mono_type (res.type);
7463 arg_size = mono_type_stack_size (res.type, &align);
7464 #if defined(__arm__) || defined(__mips__)
7465 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7467 res.value = iter->args;
7468 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7469 /* Values are stored as 8 byte register sized objects, but 'value'
7470 * is dereferenced as a pointer in other routines.
7472 res.value = (char*)res.value + 4;
7474 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7475 if (arg_size <= sizeof (gpointer)) {
7477 int padding = arg_size - mono_type_size (res.type, &dummy);
7478 res.value = (guint8*)res.value + padding;
7481 iter->args = (char*)iter->args + arg_size;
7484 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7489 ICALL_EXPORT MonoTypedRef
7490 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7492 guint32 i, arg_size;
7496 i = iter->sig->sentinelpos + iter->next_arg;
7498 g_assert (i < iter->sig->param_count);
7500 while (i < iter->sig->param_count) {
7501 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7503 res.type = iter->sig->params [i];
7504 res.klass = mono_class_from_mono_type (res.type);
7505 /* FIXME: endianess issue... */
7506 arg_size = mono_type_stack_size (res.type, &align);
7507 #if defined(__arm__) || defined(__mips__)
7508 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7510 res.value = iter->args;
7511 iter->args = (char*)iter->args + arg_size;
7513 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7516 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7524 ICALL_EXPORT MonoType*
7525 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7529 i = iter->sig->sentinelpos + iter->next_arg;
7531 g_assert (i < iter->sig->param_count);
7533 return iter->sig->params [i];
7536 ICALL_EXPORT MonoObject*
7537 mono_TypedReference_ToObject (MonoTypedRef* tref)
7540 MonoObject *result = NULL;
7541 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7542 MonoObject** objp = (MonoObject **)tref->value;
7546 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7547 mono_error_set_pending_exception (&error);
7551 ICALL_EXPORT MonoTypedRef
7552 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7555 MonoReflectionField *f;
7557 MonoType *ftype = NULL;
7561 memset (&res, 0, sizeof (res));
7564 g_assert (mono_array_length (fields) > 0);
7566 klass = target->vtable->klass;
7568 for (i = 0; i < mono_array_length (fields); ++i) {
7569 f = mono_array_get (fields, MonoReflectionField*, i);
7571 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7574 if (f->field->parent != klass) {
7575 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7579 p = (guint8*)target + f->field->offset;
7581 p += f->field->offset - sizeof (MonoObject);
7582 klass = mono_class_from_mono_type (f->field->type);
7583 ftype = f->field->type;
7587 res.klass = mono_class_from_mono_type (ftype);
7594 prelink_method (MonoMethod *method, MonoError *error)
7596 const char *exc_class, *exc_arg;
7598 mono_error_init (error);
7599 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7601 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7603 mono_error_set_exception_instance (error,
7604 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7607 /* create the wrapper, too? */
7611 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7615 prelink_method (method->method, &error);
7616 mono_error_set_pending_exception (&error);
7620 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7623 MonoClass *klass = mono_class_from_mono_type (type->type);
7625 gpointer iter = NULL;
7627 mono_class_init_checked (klass, &error);
7628 if (mono_error_set_pending_exception (&error))
7631 while ((m = mono_class_get_methods (klass, &iter))) {
7632 prelink_method (m, &error);
7633 if (mono_error_set_pending_exception (&error))
7638 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7640 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7641 gint32 const **exponents,
7642 gunichar2 const **digitLowerTable,
7643 gunichar2 const **digitUpperTable,
7644 gint64 const **tenPowersList,
7645 gint32 const **decHexDigits)
7647 *mantissas = Formatter_MantissaBitsTable;
7648 *exponents = Formatter_TensExponentTable;
7649 *digitLowerTable = Formatter_DigitLowerTable;
7650 *digitUpperTable = Formatter_DigitUpperTable;
7651 *tenPowersList = Formatter_TenPowersList;
7652 *decHexDigits = Formatter_DecHexDigits;
7656 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7657 * and avoid useless allocations.
7660 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7662 MonoReflectionType *rt;
7666 mono_error_init (error);
7667 for (i = 0; i < type->num_mods; ++i) {
7668 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7673 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7674 return_val_if_nok (error, NULL);
7676 for (i = 0; i < type->num_mods; ++i) {
7677 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7678 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7679 return_val_if_nok (error, NULL);
7681 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7682 return_val_if_nok (error, NULL);
7684 mono_array_setref (res, count, rt);
7691 ICALL_EXPORT MonoArray*
7692 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7695 MonoType *type = param->ClassImpl->type;
7696 MonoClass *member_class = mono_object_class (param->MemberImpl);
7697 MonoMethod *method = NULL;
7700 MonoMethodSignature *sig;
7703 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7704 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7705 method = rmethod->method;
7706 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7707 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7708 if (!(method = prop->property->get))
7709 method = prop->property->set;
7712 char *type_name = mono_type_get_full_name (member_class);
7713 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7714 MonoException *ex = mono_get_exception_not_supported (msg);
7717 mono_set_pending_exception (ex);
7721 image = method->klass->image;
7722 pos = param->PositionImpl;
7723 sig = mono_method_signature (method);
7727 type = sig->params [pos];
7729 res = type_array_from_modifiers (image, type, optional, &error);
7730 mono_error_set_pending_exception (&error);
7735 get_property_type (MonoProperty *prop)
7737 MonoMethodSignature *sig;
7739 sig = mono_method_signature (prop->get);
7741 } else if (prop->set) {
7742 sig = mono_method_signature (prop->set);
7743 return sig->params [sig->param_count - 1];
7748 ICALL_EXPORT MonoArray*
7749 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7752 MonoType *type = get_property_type (property->property);
7753 MonoImage *image = property->klass->image;
7758 res = type_array_from_modifiers (image, type, optional, &error);
7759 mono_error_set_pending_exception (&error);
7764 *Construct a MonoType suited to be used to decode a constant blob object.
7766 * @type is the target type which will be constructed
7767 * @blob_type is the blob type, for example, that comes from the constant table
7768 * @real_type is the expected constructed type.
7771 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7773 type->type = blob_type;
7774 type->data.klass = NULL;
7775 if (blob_type == MONO_TYPE_CLASS)
7776 type->data.klass = mono_defaults.object_class;
7777 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7778 /* For enums, we need to use the base type */
7779 type->type = MONO_TYPE_VALUETYPE;
7780 type->data.klass = mono_class_from_mono_type (real_type);
7782 type->data.klass = mono_class_from_mono_type (real_type);
7785 ICALL_EXPORT MonoObject*
7786 property_info_get_default_value (MonoReflectionProperty *property)
7790 MonoProperty *prop = property->property;
7791 MonoType *type = get_property_type (prop);
7792 MonoDomain *domain = mono_object_domain (property);
7793 MonoTypeEnum def_type;
7794 const char *def_value;
7797 mono_class_init (prop->parent);
7799 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7800 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7804 def_value = mono_class_get_property_default_value (prop, &def_type);
7806 mono_type_from_blob_type (&blob_type, def_type, type);
7807 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7809 mono_error_set_pending_exception (&error);
7813 ICALL_EXPORT MonoBoolean
7814 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7817 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7818 MonoCustomAttrInfo *cinfo;
7821 mono_class_init_checked (attr_class, &error);
7822 if (mono_error_set_pending_exception (&error))
7825 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7826 if (!is_ok (&error)) {
7827 mono_error_set_pending_exception (&error);
7832 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7834 mono_custom_attrs_free (cinfo);
7838 ICALL_EXPORT MonoArray*
7839 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7841 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7846 mono_class_init_checked (attr_class, &error);
7847 if (mono_error_set_pending_exception (&error))
7851 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7852 if (!mono_error_ok (&error)) {
7853 mono_error_set_pending_exception (&error);
7860 ICALL_EXPORT MonoArray*
7861 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7865 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7866 mono_error_set_pending_exception (&error);
7871 ICALL_EXPORT MonoStringHandle
7872 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7875 MonoStringHandle display_name;
7877 mono_error_init (error);
7878 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7879 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7881 return display_name;
7885 static inline gint32
7886 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7888 return WAIT_TIMEOUT;
7890 #endif /* !HOST_WIN32 */
7893 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7895 return mono_icall_wait_for_input_idle (handle, milliseconds);
7899 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7901 return mono_process_current_pid ();
7904 ICALL_EXPORT MonoBoolean
7905 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7917 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7919 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7923 ICALL_EXPORT MonoObject*
7924 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7926 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7931 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7933 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7937 ICALL_EXPORT MonoObject*
7938 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7940 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7944 ICALL_EXPORT MonoBoolean
7945 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7947 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7952 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7954 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7958 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7960 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7965 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7967 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7971 ICALL_EXPORT mono_unichar2*
7972 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7974 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7981 #ifndef DISABLE_ICALL_TABLES
7983 #define ICALL_TYPE(id,name,first)
7984 #define ICALL(id,name,func) Icall_ ## id,
7985 #define HANDLES(inner) inner
7988 #include "metadata/icall-def.h"
7994 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7995 #define ICALL(id,name,func)
7997 #define HANDLES(inner) inner
7999 #include "metadata/icall-def.h"
8005 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8006 #define ICALL(id,name,func)
8008 #define HANDLES(inner) inner
8010 guint16 first_icall;
8013 static const IcallTypeDesc
8014 icall_type_descs [] = {
8015 #include "metadata/icall-def.h"
8019 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8022 #define HANDLES(inner) inner
8024 #define ICALL_TYPE(id,name,first)
8027 #ifdef HAVE_ARRAY_ELEM_INIT
8028 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8029 #define MSGSTRFIELD1(line) str##line
8031 static const struct msgstrtn_t {
8032 #define ICALL(id,name,func)
8034 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8035 #include "metadata/icall-def.h"
8037 } icall_type_names_str = {
8038 #define ICALL_TYPE(id,name,first) (name),
8039 #include "metadata/icall-def.h"
8042 static const guint16 icall_type_names_idx [] = {
8043 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8044 #include "metadata/icall-def.h"
8047 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8049 static const struct msgstr_t {
8051 #define ICALL_TYPE(id,name,first)
8052 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8053 #include "metadata/icall-def.h"
8055 } icall_names_str = {
8056 #define ICALL(id,name,func) (name),
8057 #include "metadata/icall-def.h"
8060 static const guint16 icall_names_idx [] = {
8061 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8062 #include "metadata/icall-def.h"
8065 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8071 #define ICALL_TYPE(id,name,first) name,
8072 #define ICALL(id,name,func)
8073 static const char* const
8074 icall_type_names [] = {
8075 #include "metadata/icall-def.h"
8079 #define icall_type_name_get(id) (icall_type_names [(id)])
8083 #define ICALL_TYPE(id,name,first)
8084 #define ICALL(id,name,func) name,
8085 static const char* const
8087 #include "metadata/icall-def.h"
8090 #define icall_name_get(id) icall_names [(id)]
8092 #endif /* !HAVE_ARRAY_ELEM_INIT */
8095 #define HANDLES(inner) inner
8098 #define ICALL_TYPE(id,name,first)
8099 #define ICALL(id,name,func) func,
8100 static const gconstpointer
8101 icall_functions [] = {
8102 #include "metadata/icall-def.h"
8106 #ifdef ENABLE_ICALL_SYMBOL_MAP
8108 #define HANDLES(inner) inner
8111 #define ICALL_TYPE(id,name,first)
8112 #define ICALL(id,name,func) #func,
8113 static const gconstpointer
8114 icall_symbols [] = {
8115 #include "metadata/icall-def.h"
8122 #define ICALL_TYPE(id,name,first)
8123 #define ICALL(id,name,func) 0,
8125 #define HANDLES(inner) 1,
8127 icall_uses_handles [] = {
8128 #include "metadata/icall-def.h"
8133 #endif /* DISABLE_ICALL_TABLES */
8135 static mono_mutex_t icall_mutex;
8136 static GHashTable *icall_hash = NULL;
8137 static GHashTable *jit_icall_hash_name = NULL;
8138 static GHashTable *jit_icall_hash_addr = NULL;
8141 mono_icall_init (void)
8143 #ifndef DISABLE_ICALL_TABLES
8146 /* check that tables are sorted: disable in release */
8149 const char *prev_class = NULL;
8150 const char *prev_method;
8152 for (i = 0; i < Icall_type_num; ++i) {
8153 const IcallTypeDesc *desc;
8156 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8157 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8158 prev_class = icall_type_name_get (i);
8159 desc = &icall_type_descs [i];
8160 num_icalls = icall_desc_num_icalls (desc);
8161 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8162 for (j = 0; j < num_icalls; ++j) {
8163 const char *methodn = icall_name_get (desc->first_icall + j);
8164 if (prev_method && strcmp (prev_method, methodn) >= 0)
8165 g_print ("method %s should come before method %s\n", methodn, prev_method);
8166 prev_method = methodn;
8172 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8173 mono_os_mutex_init (&icall_mutex);
8177 mono_icall_lock (void)
8179 mono_locks_os_acquire (&icall_mutex, IcallLock);
8183 mono_icall_unlock (void)
8185 mono_locks_os_release (&icall_mutex, IcallLock);
8189 mono_icall_cleanup (void)
8191 g_hash_table_destroy (icall_hash);
8192 g_hash_table_destroy (jit_icall_hash_name);
8193 g_hash_table_destroy (jit_icall_hash_addr);
8194 mono_os_mutex_destroy (&icall_mutex);
8198 * mono_add_internal_call:
8199 * @name: method specification to surface to the managed world
8200 * @method: pointer to a C method to invoke when the method is called
8202 * This method surfaces the C function pointed by @method as a method
8203 * that has been surfaced in managed code with the method specified in
8204 * @name as an internal call.
8206 * Internal calls are surfaced to all app domains loaded and they are
8207 * accessibly by a type with the specified name.
8209 * You must provide a fully qualified type name, that is namespaces
8210 * and type name, followed by a colon and the method name, with an
8211 * optional signature to bind.
8213 * For example, the following are all valid declarations:
8215 * "MyApp.Services.ScriptService:Accelerate"
8216 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8218 * You use method parameters in cases where there might be more than
8219 * one surface method to managed code. That way you can register different
8220 * internal calls for different method overloads.
8222 * The internal calls are invoked with no marshalling. This means that .NET
8223 * types like System.String are exposed as `MonoString *` parameters. This is
8224 * different than the way that strings are surfaced in P/Invoke.
8226 * For more information on how the parameters are marshalled, see the
8227 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8230 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8231 * reference for more information on the format of method descriptions.
8234 mono_add_internal_call (const char *name, gconstpointer method)
8238 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8240 mono_icall_unlock ();
8243 #ifndef DISABLE_ICALL_TABLES
8245 #ifdef HAVE_ARRAY_ELEM_INIT
8247 compare_method_imap (const void *key, const void *elem)
8249 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8250 return strcmp (key, method_name);
8254 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8256 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);
8259 return (nameslot - &icall_names_idx [0]);
8263 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8265 gsize slotnum = find_slot_icall (imap, name);
8268 return (gboolean)icall_uses_handles [slotnum];
8272 find_method_icall (const IcallTypeDesc *imap, const char *name)
8274 gsize slotnum = find_slot_icall (imap, name);
8277 return (gpointer)icall_functions [slotnum];
8281 compare_class_imap (const void *key, const void *elem)
8283 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8284 return strcmp (key, class_name);
8287 static const IcallTypeDesc*
8288 find_class_icalls (const char *name)
8290 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);
8293 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8296 #else /* HAVE_ARRAY_ELEM_INIT */
8299 compare_method_imap (const void *key, const void *elem)
8301 const char** method_name = (const char**)elem;
8302 return strcmp (key, *method_name);
8306 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8308 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8311 return nameslot - icall_names;
8315 find_method_icall (const IcallTypeDesc *imap, const char *name)
8317 gsize slotnum = find_slot_icall (imap, name);
8320 return (gpointer)icall_functions [slotnum];
8324 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8326 gsize slotnum = find_slot_icall (imap, name);
8329 return (gboolean)icall_uses_handles [slotnum];
8333 compare_class_imap (const void *key, const void *elem)
8335 const char** class_name = (const char**)elem;
8336 return strcmp (key, *class_name);
8339 static const IcallTypeDesc*
8340 find_class_icalls (const char *name)
8342 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8345 return &icall_type_descs [nameslot - icall_type_names];
8348 #endif /* HAVE_ARRAY_ELEM_INIT */
8350 #endif /* DISABLE_ICALL_TABLES */
8353 * we should probably export this as an helper (handle nested types).
8354 * Returns the number of chars written in buf.
8357 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8359 int nspacelen, cnamelen;
8360 nspacelen = strlen (klass->name_space);
8361 cnamelen = strlen (klass->name);
8362 if (nspacelen + cnamelen + 2 > bufsize)
8365 memcpy (buf, klass->name_space, nspacelen);
8366 buf [nspacelen ++] = '.';
8368 memcpy (buf + nspacelen, klass->name, cnamelen);
8369 buf [nspacelen + cnamelen] = 0;
8370 return nspacelen + cnamelen;
8373 #ifdef DISABLE_ICALL_TABLES
8375 no_icall_table (void)
8377 g_assert_not_reached ();
8382 * mono_lookup_internal_call_full:
8383 * @method: the method to look up
8384 * @uses_handles: out argument if method needs handles around managed objects.
8386 * Returns a pointer to the icall code for the given method. If
8387 * uses_handles is not NULL, it will be set to TRUE if the method
8388 * needs managed objects wrapped using the infrastructure in handle.h
8390 * If the method is not found, warns and returns NULL.
8393 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8398 int typelen = 0, mlen, siglen;
8400 #ifndef DISABLE_ICALL_TABLES
8401 const IcallTypeDesc *imap = NULL;
8404 g_assert (method != NULL);
8406 if (method->is_inflated)
8407 method = ((MonoMethodInflated *) method)->declaring;
8409 if (method->klass->nested_in) {
8410 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8414 mname [pos++] = '/';
8417 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8423 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8428 #ifndef DISABLE_ICALL_TABLES
8429 imap = find_class_icalls (mname);
8432 mname [typelen] = ':';
8433 mname [typelen + 1] = ':';
8435 mlen = strlen (method->name);
8436 memcpy (mname + typelen + 2, method->name, mlen);
8437 sigstart = mname + typelen + 2 + mlen;
8440 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8441 siglen = strlen (tmpsig);
8442 if (typelen + mlen + siglen + 6 > sizeof (mname))
8445 memcpy (sigstart + 1, tmpsig, siglen);
8446 sigstart [siglen + 1] = ')';
8447 sigstart [siglen + 2] = 0;
8452 res = g_hash_table_lookup (icall_hash, mname);
8455 *uses_handles = FALSE;
8456 mono_icall_unlock ();;
8459 /* try without signature */
8461 res = g_hash_table_lookup (icall_hash, mname);
8464 *uses_handles = FALSE;
8465 mono_icall_unlock ();
8469 #ifdef DISABLE_ICALL_TABLES
8470 mono_icall_unlock ();
8471 /* Fail only when the result is actually used */
8472 /* mono_marshal_get_native_wrapper () depends on this */
8473 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8474 return ves_icall_System_String_ctor_RedirectToCreateString;
8476 return no_icall_table;
8478 /* it wasn't found in the static call tables */
8481 *uses_handles = FALSE;
8482 mono_icall_unlock ();
8485 res = find_method_icall (imap, sigstart - mlen);
8488 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8489 mono_icall_unlock ();
8492 /* try _with_ signature */
8494 res = find_method_icall (imap, sigstart - mlen);
8497 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8498 mono_icall_unlock ();
8502 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8503 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8504 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8505 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8506 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");
8507 g_print ("If you see other errors or faults after this message they are probably related\n");
8508 g_print ("and you need to fix your mono install first.\n");
8510 mono_icall_unlock ();
8517 mono_lookup_internal_call (MonoMethod *method)
8519 return mono_lookup_internal_call_full (method, NULL);
8522 #ifdef ENABLE_ICALL_SYMBOL_MAP
8524 func_cmp (gconstpointer key, gconstpointer p)
8526 return (gsize)key - (gsize)*(gsize*)p;
8531 * mono_lookup_icall_symbol:
8533 * Given the icall METHOD, returns its C symbol.
8536 mono_lookup_icall_symbol (MonoMethod *m)
8538 #ifdef DISABLE_ICALL_TABLES
8539 g_assert_not_reached ();
8542 #ifdef ENABLE_ICALL_SYMBOL_MAP
8546 static gconstpointer *functions_sorted;
8547 static const char**symbols_sorted;
8548 static gboolean inited;
8553 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8554 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8555 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8556 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8557 /* Bubble sort the two arrays */
8561 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8562 if (functions_sorted [i] > functions_sorted [i + 1]) {
8565 tmp = functions_sorted [i];
8566 functions_sorted [i] = functions_sorted [i + 1];
8567 functions_sorted [i + 1] = tmp;
8568 tmp = symbols_sorted [i];
8569 symbols_sorted [i] = symbols_sorted [i + 1];
8570 symbols_sorted [i + 1] = tmp;
8577 func = mono_lookup_internal_call (m);
8580 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8584 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8586 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8587 g_assert_not_reached ();
8594 type_from_typename (char *type_name)
8596 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8598 if (!strcmp (type_name, "int"))
8599 klass = mono_defaults.int_class;
8600 else if (!strcmp (type_name, "ptr"))
8601 klass = mono_defaults.int_class;
8602 else if (!strcmp (type_name, "void"))
8603 klass = mono_defaults.void_class;
8604 else if (!strcmp (type_name, "int32"))
8605 klass = mono_defaults.int32_class;
8606 else if (!strcmp (type_name, "uint32"))
8607 klass = mono_defaults.uint32_class;
8608 else if (!strcmp (type_name, "int8"))
8609 klass = mono_defaults.sbyte_class;
8610 else if (!strcmp (type_name, "uint8"))
8611 klass = mono_defaults.byte_class;
8612 else if (!strcmp (type_name, "int16"))
8613 klass = mono_defaults.int16_class;
8614 else if (!strcmp (type_name, "uint16"))
8615 klass = mono_defaults.uint16_class;
8616 else if (!strcmp (type_name, "long"))
8617 klass = mono_defaults.int64_class;
8618 else if (!strcmp (type_name, "ulong"))
8619 klass = mono_defaults.uint64_class;
8620 else if (!strcmp (type_name, "float"))
8621 klass = mono_defaults.single_class;
8622 else if (!strcmp (type_name, "double"))
8623 klass = mono_defaults.double_class;
8624 else if (!strcmp (type_name, "object"))
8625 klass = mono_defaults.object_class;
8626 else if (!strcmp (type_name, "obj"))
8627 klass = mono_defaults.object_class;
8628 else if (!strcmp (type_name, "string"))
8629 klass = mono_defaults.string_class;
8630 else if (!strcmp (type_name, "bool"))
8631 klass = mono_defaults.boolean_class;
8632 else if (!strcmp (type_name, "boolean"))
8633 klass = mono_defaults.boolean_class;
8635 g_error ("%s", type_name);
8636 g_assert_not_reached ();
8638 return &klass->byval_arg;
8642 * LOCKING: Take the corlib image lock.
8644 MonoMethodSignature*
8645 mono_create_icall_signature (const char *sigstr)
8650 MonoMethodSignature *res, *res2;
8651 MonoImage *corlib = mono_defaults.corlib;
8653 mono_image_lock (corlib);
8654 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8655 mono_image_unlock (corlib);
8660 parts = g_strsplit (sigstr, " ", 256);
8669 res = mono_metadata_signature_alloc (corlib, len - 1);
8674 * Under windows, the default pinvoke calling convention is STDCALL but
8677 res->call_convention = MONO_CALL_C;
8680 res->ret = type_from_typename (parts [0]);
8681 for (i = 1; i < len; ++i) {
8682 res->params [i - 1] = type_from_typename (parts [i]);
8687 mono_image_lock (corlib);
8688 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8690 res = res2; /*Value is allocated in the image pool*/
8692 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8693 mono_image_unlock (corlib);
8699 mono_find_jit_icall_by_name (const char *name)
8701 MonoJitICallInfo *info;
8702 g_assert (jit_icall_hash_name);
8705 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8706 mono_icall_unlock ();
8711 mono_find_jit_icall_by_addr (gconstpointer addr)
8713 MonoJitICallInfo *info;
8714 g_assert (jit_icall_hash_addr);
8717 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8718 mono_icall_unlock ();
8724 * mono_get_jit_icall_info:
8726 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8727 * caller should access it while holding the icall lock.
8730 mono_get_jit_icall_info (void)
8732 return jit_icall_hash_name;
8736 * mono_lookup_jit_icall_symbol:
8738 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8741 mono_lookup_jit_icall_symbol (const char *name)
8743 MonoJitICallInfo *info;
8744 const char *res = NULL;
8747 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8749 res = info->c_symbol;
8750 mono_icall_unlock ();
8755 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8758 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8759 mono_icall_unlock ();
8763 * 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
8764 * icalls without wrappers in some cases.
8767 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8769 MonoJitICallInfo *info;
8776 if (!jit_icall_hash_name) {
8777 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8778 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8781 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8782 g_warning ("jit icall already defined \"%s\"\n", name);
8783 g_assert_not_reached ();
8786 info = g_new0 (MonoJitICallInfo, 1);
8791 info->c_symbol = c_symbol;
8792 info->no_raise = no_raise;
8795 info->wrapper = func;
8797 info->wrapper = NULL;
8800 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8801 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8803 mono_icall_unlock ();
8808 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8810 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);