5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool.h>
40 #include <mono/metadata/threadpool-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/metadata-internals.h>
56 #include <mono/metadata/class-internals.h>
57 #include <mono/metadata/reflection-internals.h>
58 #include <mono/metadata/marshal.h>
59 #include <mono/metadata/gc-internals.h>
60 #include <mono/metadata/mono-gc.h>
61 #include <mono/metadata/rand.h>
62 #include <mono/metadata/sysmath.h>
63 #include <mono/metadata/appdomain-icalls.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssemblyHandle ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
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)
4691 char *guid = mono_runtime_get_aotid ();
4694 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4699 static MonoAssemblyName*
4700 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4702 mono_error_init (error);
4703 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4705 mono_assembly_get_assemblyref (image, i, aname);
4706 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4707 /* name and culture are pointers into the image tables, but we need
4708 * real malloc'd strings (so that we can g_free() them later from
4709 * Mono.RuntimeMarshal.FreeAssemblyName) */
4710 aname->name = g_strdup (aname->name);
4711 aname->culture = g_strdup (aname->culture);
4712 /* Don't need the hash value in managed */
4713 aname->hash_value = NULL;
4714 aname->hash_len = 0;
4715 g_assert (aname->public_key == NULL);
4717 /* note: this function doesn't return the codebase on purpose (i.e. it can
4718 be used under partial trust as path information isn't present). */
4722 ICALL_EXPORT GPtrArray*
4723 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4725 mono_error_init (error);
4726 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4727 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4728 MonoImage *image = ass->image;
4730 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4731 int count = t->rows;
4733 GPtrArray *result = g_ptr_array_sized_new (count);
4735 for (int i = 0; i < count; i++) {
4736 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4739 g_ptr_array_add (result, aname);
4744 /* move this in some file in mono/util/ */
4746 g_concat_dir_and_file (const char *dir, const char *file)
4748 g_return_val_if_fail (dir != NULL, NULL);
4749 g_return_val_if_fail (file != NULL, NULL);
4752 * If the directory name doesn't have a / on the end, we need
4753 * to add one so we get a proper path to the file
4755 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4756 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4758 return g_strconcat (dir, file, NULL);
4762 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4764 mono_error_init (error);
4765 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4766 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4767 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4769 guint32 cols [MONO_MANIFEST_SIZE];
4770 guint32 impl, file_idx;
4774 char *n = mono_string_handle_to_utf8 (name, error);
4775 return_val_if_nok (error, NULL);
4777 for (i = 0; i < table->rows; ++i) {
4778 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4779 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4780 if (strcmp (val, n) == 0)
4784 if (i == table->rows)
4787 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4790 * this code should only be called after obtaining the
4791 * ResourceInfo and handling the other cases.
4793 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4794 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4796 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4797 if (!is_ok (error) || !module)
4801 module = assembly->image;
4804 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4807 MONO_HANDLE_ASSIGN (ref_module, rm);
4809 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4813 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4815 HANDLE_FUNCTION_ENTER ();
4816 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4817 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4818 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4820 guint32 cols [MONO_MANIFEST_SIZE];
4821 guint32 file_cols [MONO_FILE_SIZE];
4825 gboolean result = FALSE;
4827 n = mono_string_handle_to_utf8 (name, error);
4831 for (i = 0; i < table->rows; ++i) {
4832 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4833 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4834 if (strcmp (val, n) == 0)
4838 if (i == table->rows)
4841 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4842 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4845 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4846 case MONO_IMPLEMENTATION_FILE:
4847 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4848 table = &assembly->image->tables [MONO_TABLE_FILE];
4849 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4850 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4851 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4852 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4853 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4855 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4858 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4859 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4860 mono_assembly_load_reference (assembly->image, i - 1);
4861 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4862 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4865 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4868 MONO_HANDLE_SET (info, assembly, assm_obj);
4870 /* Obtain info recursively */
4871 get_manifest_resource_info_internal (assm_obj, name, info, error);
4874 guint32 location = MONO_HANDLE_GETVAL (info, location);
4875 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4876 MONO_HANDLE_SETVAL (info, location, guint32, location);
4879 case MONO_IMPLEMENTATION_EXP_TYPE:
4880 g_assert_not_reached ();
4887 HANDLE_FUNCTION_RETURN_VAL (result);
4890 ICALL_EXPORT gboolean
4891 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4893 mono_error_init (error);
4894 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4898 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4900 HANDLE_FUNCTION_ENTER();
4901 mono_error_init (error);
4902 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4903 char *n = g_concat_dir_and_file (assembly->basedir, val);
4904 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4908 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4910 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4913 ICALL_EXPORT MonoObjectHandle
4914 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4916 mono_error_init (error);
4917 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4918 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4919 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4922 /* check hash if needed */
4923 if (!MONO_HANDLE_IS_NULL(name)) {
4924 char *n = mono_string_handle_to_utf8 (name, error);
4928 for (i = 0; i < table->rows; ++i) {
4929 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4930 if (strcmp (val, n) == 0) {
4932 n = g_concat_dir_and_file (assembly->basedir, val);
4933 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4937 return MONO_HANDLE_CAST (MonoObject, fn);
4945 for (i = 0; i < table->rows; ++i) {
4946 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4950 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4955 for (i = 0; i < table->rows; ++i) {
4956 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4957 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4962 return MONO_HANDLE_CAST (MonoObject, result);
4968 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4970 HANDLE_FUNCTION_ENTER ();
4971 mono_error_init (error);
4973 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4977 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4982 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4986 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4988 HANDLE_FUNCTION_ENTER ();
4989 mono_error_init (error);
4991 guint32 cols [MONO_FILE_SIZE];
4992 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4993 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4994 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4997 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4999 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
5003 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
5004 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5007 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
5010 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5014 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5017 ICALL_EXPORT MonoArrayHandle
5018 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5020 mono_error_init (error);
5021 MonoDomain *domain = mono_domain_get();
5022 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5024 int i, j, file_count = 0;
5025 MonoImage **modules;
5026 guint32 module_count, real_module_count;
5027 MonoTableInfo *table;
5028 MonoImage *image = assembly->image;
5030 g_assert (image != NULL);
5031 g_assert (!assembly_is_dynamic (assembly));
5033 table = &image->tables [MONO_TABLE_FILE];
5034 file_count = table->rows;
5036 modules = image->modules;
5037 module_count = image->module_count;
5039 real_module_count = 0;
5040 for (i = 0; i < module_count; ++i)
5042 real_module_count ++;
5044 klass = mono_class_get_module_class ();
5045 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5049 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5053 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5056 for (i = 0; i < module_count; ++i)
5057 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5060 for (i = 0; i < file_count; ++i, ++j) {
5061 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5067 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5070 ICALL_EXPORT MonoReflectionMethod*
5071 ves_icall_GetCurrentMethod (void)
5073 MonoReflectionMethod *res = NULL;
5076 MonoMethod *m = mono_method_get_last_managed ();
5079 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5083 while (m->is_inflated)
5084 m = ((MonoMethodInflated*)m)->declaring;
5086 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5087 mono_error_set_pending_exception (&error);
5093 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5096 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5099 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5100 //method is inflated, we should inflate it on the other class
5101 MonoGenericContext ctx;
5102 ctx.method_inst = inflated->context.method_inst;
5103 ctx.class_inst = inflated->context.class_inst;
5104 if (mono_class_is_ginst (klass))
5105 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5106 else if (mono_class_is_gtd (klass))
5107 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5108 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5109 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5113 mono_class_setup_methods (method->klass);
5114 if (mono_class_has_failure (method->klass))
5116 int mcount = mono_class_get_method_count (method->klass);
5117 for (i = 0; i < mcount; ++i) {
5118 if (method->klass->methods [i] == method) {
5123 mono_class_setup_methods (klass);
5124 if (mono_class_has_failure (klass))
5126 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5127 return klass->methods [offset];
5130 ICALL_EXPORT MonoReflectionMethod*
5131 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5133 MonoReflectionMethod *res = NULL;
5136 if (type && generic_check) {
5137 klass = mono_class_from_mono_type (type);
5138 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5141 if (method->klass != klass) {
5142 method = mono_method_get_equivalent_method (method, klass);
5147 klass = mono_class_from_mono_type (type);
5149 klass = method->klass;
5150 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5151 mono_error_set_pending_exception (&error);
5155 ICALL_EXPORT MonoReflectionMethodBody*
5156 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5159 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5160 mono_error_set_pending_exception (&error);
5164 ICALL_EXPORT MonoReflectionAssemblyHandle
5165 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5167 mono_error_init (error);
5169 MonoMethod *dest = NULL;
5170 mono_stack_walk_no_il (get_executing, &dest);
5172 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5176 ICALL_EXPORT MonoReflectionAssemblyHandle
5177 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5179 mono_error_init (error);
5181 MonoDomain* domain = mono_domain_get ();
5183 if (!domain->entry_assembly)
5184 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5186 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5189 ICALL_EXPORT MonoReflectionAssemblyHandle
5190 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5192 mono_error_init (error);
5197 mono_stack_walk_no_il (get_executing, &dest);
5199 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5203 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5204 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5206 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5209 ICALL_EXPORT MonoStringHandle
5210 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5211 gboolean assembly_qualified, MonoError *error)
5213 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5214 MonoType *type = MONO_HANDLE_RAW (object)->type;
5215 MonoTypeNameFormat format;
5216 MonoStringHandle res;
5220 format = assembly_qualified ?
5221 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5222 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5224 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5226 name = mono_type_get_name_full (type, format);
5228 return NULL_HANDLE_STRING;
5230 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5232 return NULL_HANDLE_STRING;
5235 res = mono_string_new_handle (domain, name, error);
5242 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5245 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5247 mono_class_init_checked (klass, &error);
5248 mono_error_set_pending_exception (&error);
5249 return mono_security_core_clr_class_level (klass);
5253 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5255 MonoClassField *field = rfield->field;
5256 return mono_security_core_clr_field_level (field, TRUE);
5260 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5262 MonoMethod *method = rfield->method;
5263 return mono_security_core_clr_method_level (method, TRUE);
5266 ICALL_EXPORT MonoStringHandle
5267 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5269 mono_error_init (error);
5270 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5271 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5274 name = mono_stringify_assembly_name (&mass->aname);
5275 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5280 ICALL_EXPORT MonoAssemblyName *
5281 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5283 return &mass->aname;
5287 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5290 MonoImageOpenStatus status = MONO_IMAGE_OK;
5291 char *codebase = NULL;
5296 mono_error_init (error);
5298 filename = mono_string_handle_to_utf8 (fname, error);
5299 return_if_nok (error);
5301 dirname = g_path_get_dirname (filename);
5302 replace_shadow_path (mono_domain_get (), dirname, &filename);
5305 image = mono_image_open (filename, &status);
5308 if (status == MONO_IMAGE_IMAGE_INVALID)
5309 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5311 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5316 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5318 mono_image_close (image);
5320 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5324 if (filename != NULL && *filename != '\0') {
5327 codebase = g_strdup (filename);
5329 mono_icall_make_platform_path (codebase);
5331 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5333 result = g_strconcat (prepend, codebase, NULL);
5337 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5340 mono_image_close (image);
5344 ICALL_EXPORT MonoBoolean
5345 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5346 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5348 mono_error_init (error);
5349 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5350 MonoBoolean result = FALSE;
5351 MonoDeclSecurityEntry entry;
5353 /* SecurityAction.RequestMinimum */
5354 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5355 *minimum = entry.blob;
5356 *minLength = entry.size;
5359 /* SecurityAction.RequestOptional */
5360 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5361 *optional = entry.blob;
5362 *optLength = entry.size;
5365 /* SecurityAction.RequestRefuse */
5366 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5367 *refused = entry.blob;
5368 *refLength = entry.size;
5376 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5378 guint32 attrs, visibility;
5380 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5381 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5382 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5385 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5391 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5393 mono_error_init (error);
5394 HANDLE_FUNCTION_ENTER ();
5395 MonoError klass_error;
5396 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5399 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5400 return_if_nok (error);
5402 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5404 MonoException *ex = mono_error_convert_to_exception (error);
5405 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5407 HANDLE_FUNCTION_RETURN ();
5410 static MonoArrayHandle
5411 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5413 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5416 mono_error_init (error);
5418 /* we start the count from 1 because we skip the special type <Module> */
5421 for (i = 1; i < tdef->rows; ++i) {
5422 if (mono_module_type_is_visible (tdef, image, i + 1))
5426 count = tdef->rows - 1;
5428 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5429 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5430 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5431 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5433 for (i = 1; i < tdef->rows; ++i) {
5434 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5435 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5436 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5445 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5447 HANDLE_FUNCTION_ENTER ();
5448 mono_error_init (error);
5449 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5450 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5454 /* Append the new types to the end of the array */
5455 if (mono_array_handle_length (res2) > 0) {
5458 len1 = mono_array_handle_length (res);
5459 len2 = mono_array_handle_length (res2);
5461 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5465 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5466 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5467 MONO_HANDLE_ASSIGN (res, res3);
5469 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5473 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5474 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5475 MONO_HANDLE_ASSIGN (exceptions, ex3);
5478 HANDLE_FUNCTION_RETURN ();
5482 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5484 HANDLE_FUNCTION_ENTER ();
5485 MonoError unboxed_error;
5486 mono_error_init (&unboxed_error);
5487 mono_error_set_for_class_failure (&unboxed_error, klass);
5489 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5490 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5491 HANDLE_FUNCTION_RETURN ();
5494 ICALL_EXPORT MonoArrayHandle
5495 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5497 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5500 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5501 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5503 g_assert (!assembly_is_dynamic (assembly));
5504 MonoImage *image = assembly->image;
5505 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5506 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5507 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5509 /* Append data from all modules in the assembly */
5510 for (i = 0; i < table->rows; ++i) {
5511 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5512 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5513 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5516 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5517 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5522 /* the ReflectionTypeLoadException must have all the types (Types property),
5523 * NULL replacing types which throws an exception. The LoaderException must
5524 * contain all exceptions for NULL items.
5527 int len = mono_array_handle_length (res);
5531 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5532 for (i = 0; i < len; i++) {
5533 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5535 if (!MONO_HANDLE_IS_NULL (t)) {
5536 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5537 if ((klass != NULL) && mono_class_has_failure (klass)) {
5538 /* keep the class in the list */
5539 list = g_list_append (list, klass);
5540 /* and replace Type with NULL */
5541 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5548 if (list || ex_count) {
5550 int j, length = g_list_length (list) + ex_count;
5552 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5553 if (!is_ok (error)) {
5555 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5557 /* Types for which mono_class_get_checked () succeeded */
5558 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5559 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5560 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5562 /* Types for which it don't */
5563 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5564 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5565 if (!MONO_HANDLE_IS_NULL (exc)) {
5566 g_assert (i < length);
5567 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5574 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5575 if (!is_ok (error)) {
5576 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5578 mono_error_set_exception_handle (error, exc);
5579 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5586 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5588 mono_assembly_name_free (aname);
5593 ICALL_EXPORT gboolean
5594 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5596 *is_version_definited = *is_token_defined = FALSE;
5598 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5601 ICALL_EXPORT MonoReflectionTypeHandle
5602 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5604 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5605 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5610 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5612 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5613 /* These images do not have a global type */
5616 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5620 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5626 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5628 /*if (module->image)
5629 mono_image_close (module->image);*/
5632 ICALL_EXPORT MonoStringHandle
5633 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5635 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5636 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5639 return mono_string_new_handle (domain, image->guid, error);
5643 static inline gpointer
5644 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5646 return (gpointer) (-1);
5648 #endif /* HOST_WIN32 */
5650 ICALL_EXPORT gpointer
5651 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5653 return mono_icall_module_get_hinstance (module);
5657 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5659 if (image_is_dynamic (image)) {
5660 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5661 *pe_kind = dyn->pe_kind;
5662 *machine = dyn->machine;
5665 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5666 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5671 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5673 return (image->md_version_major << 16) | (image->md_version_minor);
5676 ICALL_EXPORT MonoArrayHandle
5677 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5679 mono_error_init (error);
5681 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5682 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5685 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5688 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5689 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5690 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5692 int n = mono_array_handle_length (exceptions);
5693 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5694 for (int i = 0; i < n; ++i) {
5695 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5696 if (!MONO_HANDLE_IS_NULL (ex)) {
5697 mono_error_set_exception_handle (error, ex);
5698 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5706 mono_memberref_is_method (MonoImage *image, guint32 token)
5708 if (!image_is_dynamic (image)) {
5709 guint32 cols [MONO_MEMBERREF_SIZE];
5711 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5712 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5713 mono_metadata_decode_blob_size (sig, &sig);
5714 return (*sig != 0x6);
5717 MonoClass *handle_class;
5719 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5720 mono_error_cleanup (&error); /* just probing, ignore error */
5724 return mono_defaults.methodhandle_class == handle_class;
5729 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5732 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5733 mono_array_addr (type_args, MonoType*, 0));
5735 context->class_inst = NULL;
5737 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5738 mono_array_addr (method_args, MonoType*, 0));
5740 context->method_inst = NULL;
5743 ICALL_EXPORT MonoType*
5744 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5747 int table = mono_metadata_token_table (token);
5748 int index = mono_metadata_token_index (token);
5749 MonoGenericContext context;
5752 *resolve_error = ResolveTokenError_Other;
5754 /* Validate token */
5755 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5756 (table != MONO_TABLE_TYPESPEC)) {
5757 *resolve_error = ResolveTokenError_BadTable;
5761 if (image_is_dynamic (image)) {
5762 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5763 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5764 mono_error_cleanup (&error);
5765 return klass ? &klass->byval_arg : NULL;
5768 init_generic_context_from_args (&context, type_args, method_args);
5769 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5770 mono_error_cleanup (&error);
5771 return klass ? &klass->byval_arg : NULL;
5774 if ((index <= 0) || (index > image->tables [table].rows)) {
5775 *resolve_error = ResolveTokenError_OutOfRange;
5779 init_generic_context_from_args (&context, type_args, method_args);
5780 klass = mono_class_get_checked (image, token, &error);
5782 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5783 if (!mono_error_ok (&error)) {
5784 mono_error_set_pending_exception (&error);
5789 return &klass->byval_arg;
5794 ICALL_EXPORT MonoMethod*
5795 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5798 int table = mono_metadata_token_table (token);
5799 int index = mono_metadata_token_index (token);
5800 MonoGenericContext context;
5803 *resolve_error = ResolveTokenError_Other;
5805 /* Validate token */
5806 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5807 (table != MONO_TABLE_MEMBERREF)) {
5808 *resolve_error = ResolveTokenError_BadTable;
5812 if (image_is_dynamic (image)) {
5813 if (table == MONO_TABLE_METHOD) {
5814 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5815 mono_error_cleanup (&error);
5819 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5820 *resolve_error = ResolveTokenError_BadTable;
5824 init_generic_context_from_args (&context, type_args, method_args);
5825 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5826 mono_error_cleanup (&error);
5830 if ((index <= 0) || (index > image->tables [table].rows)) {
5831 *resolve_error = ResolveTokenError_OutOfRange;
5834 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5835 *resolve_error = ResolveTokenError_BadTable;
5839 init_generic_context_from_args (&context, type_args, method_args);
5840 method = mono_get_method_checked (image, token, NULL, &context, &error);
5841 mono_error_set_pending_exception (&error);
5846 ICALL_EXPORT MonoString*
5847 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5850 int index = mono_metadata_token_index (token);
5852 *resolve_error = ResolveTokenError_Other;
5854 /* Validate token */
5855 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5856 *resolve_error = ResolveTokenError_BadTable;
5860 if (image_is_dynamic (image)) {
5861 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5862 mono_error_cleanup (&error);
5866 if ((index <= 0) || (index >= image->heap_us.size)) {
5867 *resolve_error = ResolveTokenError_OutOfRange;
5871 /* FIXME: What to do if the index points into the middle of a string ? */
5873 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5874 mono_error_set_pending_exception (&error);
5878 ICALL_EXPORT MonoClassField*
5879 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5883 int table = mono_metadata_token_table (token);
5884 int index = mono_metadata_token_index (token);
5885 MonoGenericContext context;
5886 MonoClassField *field;
5888 *resolve_error = ResolveTokenError_Other;
5890 /* Validate token */
5891 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5892 *resolve_error = ResolveTokenError_BadTable;
5896 if (image_is_dynamic (image)) {
5897 if (table == MONO_TABLE_FIELD) {
5898 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5899 mono_error_cleanup (&error);
5903 if (mono_memberref_is_method (image, token)) {
5904 *resolve_error = ResolveTokenError_BadTable;
5908 init_generic_context_from_args (&context, type_args, method_args);
5909 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5910 mono_error_cleanup (&error);
5914 if ((index <= 0) || (index > image->tables [table].rows)) {
5915 *resolve_error = ResolveTokenError_OutOfRange;
5918 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5919 *resolve_error = ResolveTokenError_BadTable;
5923 init_generic_context_from_args (&context, type_args, method_args);
5924 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5925 mono_error_set_pending_exception (&error);
5931 ICALL_EXPORT MonoObject*
5932 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5936 int table = mono_metadata_token_table (token);
5938 *error = ResolveTokenError_Other;
5941 case MONO_TABLE_TYPEDEF:
5942 case MONO_TABLE_TYPEREF:
5943 case MONO_TABLE_TYPESPEC: {
5944 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5946 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5947 mono_error_set_pending_exception (&merror);
5954 case MONO_TABLE_METHOD:
5955 case MONO_TABLE_METHODSPEC: {
5956 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5958 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5959 mono_error_set_pending_exception (&merror);
5965 case MONO_TABLE_FIELD: {
5966 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5968 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5969 mono_error_set_pending_exception (&merror);
5975 case MONO_TABLE_MEMBERREF:
5976 if (mono_memberref_is_method (image, token)) {
5977 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5979 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5980 mono_error_set_pending_exception (&merror);
5987 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5989 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5990 mono_error_set_pending_exception (&merror);
5999 *error = ResolveTokenError_BadTable;
6005 ICALL_EXPORT MonoArray*
6006 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6009 int table = mono_metadata_token_table (token);
6010 int idx = mono_metadata_token_index (token);
6011 MonoTableInfo *tables = image->tables;
6016 *resolve_error = ResolveTokenError_OutOfRange;
6018 /* FIXME: Support other tables ? */
6019 if (table != MONO_TABLE_STANDALONESIG)
6022 if (image_is_dynamic (image))
6025 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6028 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6030 ptr = mono_metadata_blob_heap (image, sig);
6031 len = mono_metadata_decode_blob_size (ptr, &ptr);
6033 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6034 if (mono_error_set_pending_exception (&error))
6036 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6040 ICALL_EXPORT MonoBoolean
6041 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6047 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6053 check_for_invalid_type (MonoClass *klass, MonoError *error)
6057 mono_error_init (error);
6059 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6062 name = mono_type_get_full_name (klass);
6063 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6065 ICALL_EXPORT MonoReflectionType *
6066 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6069 MonoReflectionType *ret;
6070 MonoClass *klass, *aklass;
6072 klass = mono_class_from_mono_type (type->type);
6073 check_for_invalid_type (klass, &error);
6074 if (mono_error_set_pending_exception (&error))
6077 if (rank == 0) //single dimentional array
6078 aklass = mono_array_class_get (klass, 1);
6080 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6082 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6083 mono_error_set_pending_exception (&error);
6088 ICALL_EXPORT MonoReflectionType *
6089 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6092 MonoReflectionType *ret;
6095 klass = mono_class_from_mono_type (type->type);
6096 mono_class_init_checked (klass, &error);
6097 if (mono_error_set_pending_exception (&error))
6100 check_for_invalid_type (klass, &error);
6101 if (mono_error_set_pending_exception (&error))
6104 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6105 mono_error_set_pending_exception (&error);
6110 ICALL_EXPORT MonoReflectionType *
6111 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6114 MonoReflectionType *ret;
6115 MonoClass *klass, *pklass;
6117 klass = mono_class_from_mono_type (type->type);
6118 mono_class_init_checked (klass, &error);
6119 if (mono_error_set_pending_exception (&error))
6121 check_for_invalid_type (klass, &error);
6122 if (mono_error_set_pending_exception (&error))
6125 pklass = mono_ptr_class_get (type->type);
6127 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6128 mono_error_set_pending_exception (&error);
6133 ICALL_EXPORT MonoObject *
6134 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6135 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6138 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6139 MonoObject *delegate;
6141 MonoMethod *method = info->method;
6142 MonoMethodSignature *sig = mono_method_signature(method);
6144 mono_class_init_checked (delegate_class, &error);
6145 if (mono_error_set_pending_exception (&error))
6148 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6149 /* FIXME improve this exception message */
6150 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6152 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6153 mono_error_set_pending_exception (&error);
6157 if (mono_security_core_clr_enabled ()) {
6158 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6159 if (throwOnBindFailure)
6160 mono_error_set_pending_exception (&error);
6162 mono_error_cleanup (&error);
6167 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6168 if (!method->is_inflated) {
6169 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"));
6174 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6175 if (mono_error_set_pending_exception (&error))
6178 if (method_is_dynamic (method)) {
6179 /* Creating a trampoline would leak memory */
6180 func = mono_compile_method_checked (method, &error);
6181 if (mono_error_set_pending_exception (&error))
6184 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6185 method = mono_object_get_virtual_method (target, method);
6186 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6187 if (mono_error_set_pending_exception (&error))
6189 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6192 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6193 if (mono_error_set_pending_exception (&error))
6198 ICALL_EXPORT MonoMulticastDelegate *
6199 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6202 MonoMulticastDelegate *ret;
6204 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6206 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6207 if (mono_error_set_pending_exception (&error))
6210 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6215 ICALL_EXPORT MonoReflectionMethod*
6216 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6218 MonoReflectionMethod *ret = NULL;
6220 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6221 mono_error_set_pending_exception (&error);
6227 static inline gint32
6228 mono_array_get_byte_length (MonoArray *array)
6234 klass = array->obj.vtable->klass;
6236 if (array->bounds == NULL)
6237 length = array->max_length;
6240 for (i = 0; i < klass->rank; ++ i)
6241 length *= array->bounds [i].length;
6244 switch (klass->element_class->byval_arg.type) {
6247 case MONO_TYPE_BOOLEAN:
6251 case MONO_TYPE_CHAR:
6259 return length * sizeof (gpointer);
6270 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6272 return mono_array_get_byte_length (array);
6276 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6278 return mono_array_get (array, gint8, idx);
6282 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6284 mono_array_set (array, gint8, idx, value);
6287 ICALL_EXPORT MonoBoolean
6288 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6290 guint8 *src_buf, *dest_buf;
6293 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6297 g_assert (count >= 0);
6299 /* This is called directly from the class libraries without going through the managed wrapper */
6300 MONO_CHECK_ARG_NULL (src, FALSE);
6301 MONO_CHECK_ARG_NULL (dest, FALSE);
6303 /* watch out for integer overflow */
6304 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6307 src_buf = (guint8 *)src->vector + src_offset;
6308 dest_buf = (guint8 *)dest->vector + dest_offset;
6311 memcpy (dest_buf, src_buf, count);
6313 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6318 #ifndef DISABLE_REMOTING
6319 ICALL_EXPORT MonoObject *
6320 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6323 MonoDomain *domain = mono_object_domain (this_obj);
6325 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6326 MonoTransparentProxy *tp;
6330 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6331 if (mono_error_set_pending_exception (&error))
6334 tp = (MonoTransparentProxy*) res;
6336 MONO_OBJECT_SETREF (tp, rp, rp);
6337 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6338 klass = mono_class_from_mono_type (type);
6340 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6341 mono_class_setup_vtable (klass);
6342 if (mono_class_has_failure (klass)) {
6343 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6347 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6348 if (mono_error_set_pending_exception (&error))
6350 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6351 if (mono_error_set_pending_exception (&error))
6354 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6355 if (mono_error_set_pending_exception (&error))
6360 ICALL_EXPORT MonoReflectionType *
6361 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6364 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6365 mono_error_set_pending_exception (&error);
6371 /* System.Environment */
6374 ves_icall_System_Environment_get_UserName (void)
6376 /* using glib is more portable */
6377 return mono_string_new (mono_domain_get (), g_get_user_name ());
6382 mono_icall_get_machine_name (void)
6384 #if !defined(DISABLE_SOCKETS)
6388 #if defined _SC_HOST_NAME_MAX
6389 n = sysconf (_SC_HOST_NAME_MAX);
6393 buf = g_malloc (n+1);
6395 if (gethostname (buf, n) == 0){
6397 result = mono_string_new (mono_domain_get (), buf);
6404 return mono_string_new (mono_domain_get (), "mono");
6407 #endif /* !HOST_WIN32 */
6409 ICALL_EXPORT MonoString *
6410 ves_icall_System_Environment_get_MachineName (void)
6412 return mono_icall_get_machine_name ();
6417 mono_icall_get_platform (void)
6419 #if defined(__MACH__)
6422 // Notice that the value is hidden from user code, and only exposed
6423 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6424 // define and making assumptions based on Unix/128/4 values before there
6425 // was a MacOS define. Lots of code would assume that not-Unix meant
6426 // Windows, but in this case, it would be OSX.
6434 #endif /* !HOST_WIN32 */
6437 ves_icall_System_Environment_get_Platform (void)
6439 return mono_icall_get_platform ();
6443 static inline MonoString *
6444 mono_icall_get_new_line (void)
6446 return mono_string_new (mono_domain_get (), "\n");
6448 #endif /* !HOST_WIN32 */
6450 ICALL_EXPORT MonoString *
6451 ves_icall_System_Environment_get_NewLine (void)
6453 return mono_icall_get_new_line ();
6457 static inline MonoBoolean
6458 mono_icall_is_64bit_os (void)
6460 #if SIZEOF_VOID_P == 8
6463 #if defined(HAVE_SYS_UTSNAME_H)
6464 struct utsname name;
6466 if (uname (&name) >= 0) {
6467 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6473 #endif /* !HOST_WIN32 */
6475 ICALL_EXPORT MonoBoolean
6476 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6478 return mono_icall_is_64bit_os ();
6481 ICALL_EXPORT MonoStringHandle
6482 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6486 if (utf8_name == NULL)
6487 return NULL_HANDLE_STRING;
6489 value = g_getenv (utf8_name);
6492 return NULL_HANDLE_STRING;
6494 return mono_string_new_handle (mono_domain_get (), value, error);
6498 * There is no standard way to get at environ.
6501 #ifndef __MINGW32_VERSION
6502 #if defined(__APPLE__)
6503 #if defined (TARGET_OSX)
6504 /* Apple defines this in crt_externs.h but doesn't provide that header for
6505 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6506 * in fact exist on all implementations (so far)
6508 gchar ***_NSGetEnviron(void);
6509 #define environ (*_NSGetEnviron())
6511 static char *mono_environ[1] = { NULL };
6512 #define environ mono_environ
6513 #endif /* defined (TARGET_OSX) */
6521 ICALL_EXPORT MonoArray *
6522 ves_icall_System_Environment_GetCoomandLineArgs (void)
6525 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6526 mono_error_set_pending_exception (&error);
6532 mono_icall_get_environment_variable_names (void)
6542 for (e = environ; *e != 0; ++ e)
6545 domain = mono_domain_get ();
6546 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6547 if (mono_error_set_pending_exception (&error))
6551 for (e = environ; *e != 0; ++ e) {
6552 parts = g_strsplit (*e, "=", 2);
6554 str = mono_string_new (domain, *parts);
6555 mono_array_setref (names, n, str);
6565 #endif /* !HOST_WIN32 */
6567 ICALL_EXPORT MonoArray *
6568 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6570 return mono_icall_get_environment_variable_names ();
6575 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6577 gchar *utf8_name, *utf8_value;
6580 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6581 if (mono_error_set_pending_exception (&error))
6584 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6585 g_unsetenv (utf8_name);
6590 utf8_value = mono_string_to_utf8_checked (value, &error);
6591 if (!mono_error_ok (&error)) {
6593 mono_error_set_pending_exception (&error);
6596 g_setenv (utf8_name, utf8_value, TRUE);
6599 g_free (utf8_value);
6601 #endif /* !HOST_WIN32 */
6604 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6606 mono_icall_set_environment_variable (name, value);
6610 ves_icall_System_Environment_Exit (int result)
6612 mono_environment_exitcode_set (result);
6614 /* FIXME: There are some cleanup hangs that should be worked out, but
6615 * if the program is going to exit, everything will be cleaned up when
6616 * NaCl exits anyway.
6618 #ifndef __native_client__
6619 if (!mono_runtime_try_shutdown ())
6620 mono_thread_exit ();
6622 /* Suspend all managed threads since the runtime is going away */
6623 mono_thread_suspend_all_other_threads ();
6625 mono_runtime_quit ();
6628 /* we may need to do some cleanup here... */
6632 ICALL_EXPORT MonoStringHandle
6633 ves_icall_System_Environment_GetGacPath (MonoError *error)
6635 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6639 static inline MonoString *
6640 mono_icall_get_windows_folder_path (int folder)
6642 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6643 return mono_string_new (mono_domain_get (), "");
6645 #endif /* !HOST_WIN32 */
6647 ICALL_EXPORT MonoString*
6648 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6650 return mono_icall_get_windows_folder_path (folder);
6653 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6655 mono_icall_get_logical_drives (void)
6658 gunichar2 buf [256], *ptr, *dname;
6660 guint initial_size = 127, size = 128;
6663 MonoString *drivestr;
6664 MonoDomain *domain = mono_domain_get ();
6670 while (size > initial_size) {
6671 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6672 if (size > initial_size) {
6675 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6676 initial_size = size;
6690 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6691 if (mono_error_set_pending_exception (&error))
6698 while (*u16) { u16++; len ++; }
6699 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6700 if (mono_error_set_pending_exception (&error))
6703 mono_array_setref (result, ndrives++, drivestr);
6713 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6715 ICALL_EXPORT MonoArray *
6716 ves_icall_System_Environment_GetLogicalDrives (void)
6718 return mono_icall_get_logical_drives ();
6721 ICALL_EXPORT MonoString *
6722 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6725 gunichar2 volume_name [MAX_PATH + 1];
6727 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6729 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6730 mono_error_set_pending_exception (&error);
6734 ICALL_EXPORT MonoStringHandle
6735 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6737 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6740 static const char *encodings [] = {
6742 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6743 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6744 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6746 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6747 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6748 "x_unicode_2_0_utf_7",
6750 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6751 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6753 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6756 "unicodefffe", "utf_16be",
6763 * Returns the internal codepage, if the value of "int_code_page" is
6764 * 1 at entry, and we can not compute a suitable code page number,
6765 * returns the code page as a string
6767 ICALL_EXPORT MonoString*
6768 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6773 char *codepage = NULL;
6775 int want_name = *int_code_page;
6778 *int_code_page = -1;
6780 g_get_charset (&cset);
6781 c = codepage = g_strdup (cset);
6782 for (c = codepage; *c; c++){
6783 if (isascii (*c) && isalpha (*c))
6788 /* g_print ("charset: %s\n", cset); */
6790 /* handle some common aliases */
6793 for (i = 0; p != 0; ){
6796 p = encodings [++i];
6799 if (strcmp (p, codepage) == 0){
6800 *int_code_page = code;
6803 p = encodings [++i];
6806 if (strstr (codepage, "utf_8") != NULL)
6807 *int_code_page |= 0x10000000;
6810 if (want_name && *int_code_page == -1)
6811 return mono_string_new (mono_domain_get (), cset);
6816 ICALL_EXPORT MonoBoolean
6817 ves_icall_System_Environment_get_HasShutdownStarted (void)
6819 if (mono_runtime_is_shutting_down ())
6822 if (mono_domain_is_unloading (mono_domain_get ()))
6830 mono_icall_broadcast_setting_change (void)
6834 #endif /* !HOST_WIN32 */
6837 ves_icall_System_Environment_BroadcastSettingChange (void)
6839 mono_icall_broadcast_setting_change ();
6844 ves_icall_System_Environment_get_TickCount (void)
6846 /* this will overflow after ~24 days */
6847 return (gint32) (mono_msec_boottime () & 0xffffffff);
6851 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6856 #ifndef DISABLE_REMOTING
6857 ICALL_EXPORT MonoBoolean
6858 ves_icall_IsTransparentProxy (MonoObject *proxy)
6863 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6869 ICALL_EXPORT MonoReflectionMethod *
6870 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6871 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6873 MonoReflectionMethod *ret = NULL;
6878 MonoMethod **vtable;
6879 MonoMethod *res = NULL;
6881 MONO_CHECK_ARG_NULL (rtype, NULL);
6882 MONO_CHECK_ARG_NULL (rmethod, NULL);
6884 method = rmethod->method;
6885 klass = mono_class_from_mono_type (rtype->type);
6886 mono_class_init_checked (klass, &error);
6887 if (mono_error_set_pending_exception (&error))
6890 if (MONO_CLASS_IS_INTERFACE (klass))
6893 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6896 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6897 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6903 mono_class_setup_vtable (klass);
6904 vtable = klass->vtable;
6906 if (mono_class_is_interface (method->klass)) {
6907 gboolean variance_used = FALSE;
6908 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6909 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6911 res = vtable [offs + method->slot];
6913 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6916 if (method->slot != -1)
6917 res = vtable [method->slot];
6923 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6924 mono_error_set_pending_exception (&error);
6929 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6935 klass = mono_class_from_mono_type (type->type);
6936 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6937 if (!is_ok (&error)) {
6938 mono_error_set_pending_exception (&error);
6942 mono_vtable_set_is_remote (vtable, enable);
6945 #else /* DISABLE_REMOTING */
6948 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6950 g_assert_not_reached ();
6955 ICALL_EXPORT MonoObject *
6956 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6963 domain = mono_object_domain (type);
6964 klass = mono_class_from_mono_type (type->type);
6965 mono_class_init_checked (klass, &error);
6966 if (mono_error_set_pending_exception (&error))
6969 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6970 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6974 if (klass->rank >= 1) {
6975 g_assert (klass->rank == 1);
6976 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6977 mono_error_set_pending_exception (&error);
6980 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6981 if (!is_ok (&error)) {
6982 mono_error_set_pending_exception (&error);
6985 /* Bypass remoting object creation check */
6986 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6987 mono_error_set_pending_exception (&error);
6993 ICALL_EXPORT MonoStringHandle
6994 ves_icall_System_IO_get_temp_path (MonoError *error)
6996 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6999 #ifndef PLATFORM_NO_DRIVEINFO
7000 ICALL_EXPORT MonoBoolean
7001 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7002 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7006 ULARGE_INTEGER wapi_free_bytes_avail;
7007 ULARGE_INTEGER wapi_total_number_of_bytes;
7008 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7010 *error = ERROR_SUCCESS;
7011 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7012 &wapi_total_number_of_free_bytes);
7015 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7016 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7017 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7019 *free_bytes_avail = 0;
7020 *total_number_of_bytes = 0;
7021 *total_number_of_free_bytes = 0;
7022 *error = GetLastError ();
7028 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7029 static inline guint32
7030 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7032 return GetDriveType (mono_string_chars (root_path_name));
7034 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7036 ICALL_EXPORT guint32
7037 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7039 return mono_icall_drive_info_get_drive_type (root_path_name);
7042 #endif /* PLATFORM_NO_DRIVEINFO */
7044 ICALL_EXPORT gpointer
7045 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7048 gpointer result = mono_compile_method_checked (method, &error);
7049 mono_error_set_pending_exception (&error);
7053 ICALL_EXPORT MonoString *
7054 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7059 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7061 mono_icall_make_platform_path (path);
7063 mcpath = mono_string_new (mono_domain_get (), path);
7069 /* this is an icall */
7071 get_bundled_app_config (void)
7074 const gchar *app_config;
7077 gchar *config_file_name, *config_file_path;
7078 gsize len, config_file_path_length, config_ext_length;
7081 domain = mono_domain_get ();
7082 file = domain->setup->configuration_file;
7083 if (!file || file->length == 0)
7086 // Retrieve config file and remove the extension
7087 config_file_name = mono_string_to_utf8_checked (file, &error);
7088 if (mono_error_set_pending_exception (&error))
7090 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7091 if (!config_file_path)
7092 config_file_path = config_file_name;
7094 config_file_path_length = strlen (config_file_path);
7095 config_ext_length = strlen (".config");
7096 if (config_file_path_length <= config_ext_length)
7099 len = config_file_path_length - config_ext_length;
7100 module = (gchar *)g_malloc0 (len + 1);
7101 memcpy (module, config_file_path, len);
7102 // Get the config file from the module name
7103 app_config = mono_config_string_for_assembly_file (module);
7106 if (config_file_name != config_file_path)
7107 g_free (config_file_name);
7108 g_free (config_file_path);
7113 return mono_string_new (mono_domain_get (), app_config);
7116 static MonoStringHandle
7117 get_bundled_machine_config (MonoError *error)
7119 const gchar *machine_config;
7121 machine_config = mono_get_machine_config ();
7123 if (!machine_config)
7124 return NULL_HANDLE_STRING;
7126 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7129 ICALL_EXPORT MonoStringHandle
7130 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7132 return get_bundled_machine_config (error);
7136 ICALL_EXPORT MonoStringHandle
7137 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7139 return get_bundled_machine_config (error);
7142 ICALL_EXPORT MonoStringHandle
7143 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7145 return get_bundled_machine_config (error);
7149 ICALL_EXPORT MonoString *
7150 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7155 path = g_path_get_dirname (mono_get_config_dir ());
7157 mono_icall_make_platform_path (path);
7159 ipath = mono_string_new (mono_domain_get (), path);
7165 ICALL_EXPORT gboolean
7166 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7168 mono_error_init (error);
7169 MonoPEResourceDataEntry *entry;
7172 if (!assembly || !result || !size)
7177 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7178 image = assm->image;
7179 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7183 *result = mono_image_rva_map (image, entry->rde_data_offset);
7188 *size = entry->rde_size;
7193 ICALL_EXPORT MonoBoolean
7194 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7196 return mono_is_debugger_attached ();
7199 ICALL_EXPORT MonoBoolean
7200 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7202 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7203 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7209 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7211 if (mono_get_runtime_callbacks ()->debug_log)
7212 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7217 mono_icall_write_windows_debug_string (MonoString *message)
7219 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7221 #endif /* !HOST_WIN32 */
7224 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7226 mono_icall_write_windows_debug_string (message);
7229 /* Only used for value types */
7230 ICALL_EXPORT MonoObject *
7231 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7238 domain = mono_object_domain (type);
7239 klass = mono_class_from_mono_type (type->type);
7240 mono_class_init_checked (klass, &error);
7241 if (mono_error_set_pending_exception (&error))
7244 if (mono_class_is_nullable (klass))
7245 /* No arguments -> null */
7248 result = mono_object_new_checked (domain, klass, &error);
7249 mono_error_set_pending_exception (&error);
7253 ICALL_EXPORT MonoReflectionMethod *
7254 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7256 MonoReflectionMethod *ret = NULL;
7259 MonoClass *klass, *parent;
7260 MonoGenericContext *generic_inst = NULL;
7261 MonoMethod *method = m->method;
7262 MonoMethod *result = NULL;
7265 if (method->klass == NULL)
7268 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7269 MONO_CLASS_IS_INTERFACE (method->klass) ||
7270 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7273 slot = mono_method_get_vtable_slot (method);
7277 klass = method->klass;
7278 if (mono_class_is_ginst (klass)) {
7279 generic_inst = mono_class_get_context (klass);
7280 klass = mono_class_get_generic_class (klass)->container_class;
7285 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7286 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7287 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7288 or klass is the generic container class and generic_inst is the instantiation.
7290 when we go to the parent, if the parent is an open constructed type, we need to
7291 replace the type parameters by the definitions from the generic_inst, and then take it
7292 apart again into the klass and the generic_inst.
7294 For cases like this:
7295 class C<T> : B<T, int> {
7296 public override void Foo () { ... }
7298 class B<U,V> : A<HashMap<U,V>> {
7299 public override void Foo () { ... }
7302 public virtual void Foo () { ... }
7305 if at each iteration the parent isn't open, we can skip inflating it. if at some
7306 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7309 MonoGenericContext *parent_inst = NULL;
7310 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7311 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7312 if (!mono_error_ok (&error)) {
7313 mono_error_set_pending_exception (&error);
7317 if (mono_class_is_ginst (parent)) {
7318 parent_inst = mono_class_get_context (parent);
7319 parent = mono_class_get_generic_class (parent)->container_class;
7322 mono_class_setup_vtable (parent);
7323 if (parent->vtable_size <= slot)
7326 generic_inst = parent_inst;
7329 klass = klass->parent;
7332 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7333 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7334 if (!mono_error_ok (&error)) {
7335 mono_error_set_pending_exception (&error);
7339 generic_inst = NULL;
7341 if (mono_class_is_ginst (klass)) {
7342 generic_inst = mono_class_get_context (klass);
7343 klass = mono_class_get_generic_class (klass)->container_class;
7349 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7350 if (!mono_error_ok (&error)) {
7351 mono_error_set_pending_exception (&error);
7356 if (klass == method->klass)
7359 /*This is possible if definition == FALSE.
7360 * Do it here to be really sure we don't read invalid memory.
7362 if (slot >= klass->vtable_size)
7365 mono_class_setup_vtable (klass);
7367 result = klass->vtable [slot];
7368 if (result == NULL) {
7369 /* It is an abstract method */
7370 gboolean found = FALSE;
7371 gpointer iter = NULL;
7372 while ((result = mono_class_get_methods (klass, &iter))) {
7373 if (result->slot == slot) {
7378 /* found might be FALSE if we looked in an abstract class
7379 * that doesn't override an abstract method of its
7381 * abstract class Base {
7382 * public abstract void Foo ();
7384 * abstract class Derived : Base { }
7385 * class Child : Derived {
7386 * public override void Foo () { }
7389 * if m was Child.Foo and we ask for the base method,
7390 * then we get here with klass == Derived and found == FALSE
7392 /* but it shouldn't be the case that if we're looking
7393 * for the definition and didn't find a result; the
7394 * loop above should've taken us as far as we could
7396 g_assert (!(definition && !found));
7401 g_assert (result != NULL);
7403 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7404 mono_error_set_pending_exception (&error);
7408 ICALL_EXPORT MonoString*
7409 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7411 MonoMethod *method = m->method;
7413 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7418 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7420 iter->sig = *(MonoMethodSignature**)argsp;
7422 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7423 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7426 /* FIXME: it's not documented what start is exactly... */
7430 iter->args = argsp + sizeof (gpointer);
7432 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7434 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7437 ICALL_EXPORT MonoTypedRef
7438 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7440 guint32 i, arg_size;
7444 i = iter->sig->sentinelpos + iter->next_arg;
7446 g_assert (i < iter->sig->param_count);
7448 res.type = iter->sig->params [i];
7449 res.klass = mono_class_from_mono_type (res.type);
7450 arg_size = mono_type_stack_size (res.type, &align);
7451 #if defined(__arm__) || defined(__mips__)
7452 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7454 res.value = iter->args;
7455 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7456 /* Values are stored as 8 byte register sized objects, but 'value'
7457 * is dereferenced as a pointer in other routines.
7459 res.value = (char*)res.value + 4;
7461 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7462 if (arg_size <= sizeof (gpointer)) {
7464 int padding = arg_size - mono_type_size (res.type, &dummy);
7465 res.value = (guint8*)res.value + padding;
7468 iter->args = (char*)iter->args + arg_size;
7471 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7476 ICALL_EXPORT MonoTypedRef
7477 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7479 guint32 i, arg_size;
7483 i = iter->sig->sentinelpos + iter->next_arg;
7485 g_assert (i < iter->sig->param_count);
7487 while (i < iter->sig->param_count) {
7488 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7490 res.type = iter->sig->params [i];
7491 res.klass = mono_class_from_mono_type (res.type);
7492 /* FIXME: endianess issue... */
7493 arg_size = mono_type_stack_size (res.type, &align);
7494 #if defined(__arm__) || defined(__mips__)
7495 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7497 res.value = iter->args;
7498 iter->args = (char*)iter->args + arg_size;
7500 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7503 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7511 ICALL_EXPORT MonoType*
7512 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7516 i = iter->sig->sentinelpos + iter->next_arg;
7518 g_assert (i < iter->sig->param_count);
7520 return iter->sig->params [i];
7523 ICALL_EXPORT MonoObject*
7524 mono_TypedReference_ToObject (MonoTypedRef* tref)
7527 MonoObject *result = NULL;
7528 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7529 MonoObject** objp = (MonoObject **)tref->value;
7533 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7534 mono_error_set_pending_exception (&error);
7538 ICALL_EXPORT MonoTypedRef
7539 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7542 MonoReflectionField *f;
7544 MonoType *ftype = NULL;
7548 memset (&res, 0, sizeof (res));
7551 g_assert (mono_array_length (fields) > 0);
7553 klass = target->vtable->klass;
7555 for (i = 0; i < mono_array_length (fields); ++i) {
7556 f = mono_array_get (fields, MonoReflectionField*, i);
7558 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7561 if (f->field->parent != klass) {
7562 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7566 p = (guint8*)target + f->field->offset;
7568 p += f->field->offset - sizeof (MonoObject);
7569 klass = mono_class_from_mono_type (f->field->type);
7570 ftype = f->field->type;
7574 res.klass = mono_class_from_mono_type (ftype);
7581 prelink_method (MonoMethod *method, MonoError *error)
7583 const char *exc_class, *exc_arg;
7585 mono_error_init (error);
7586 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7588 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7590 mono_error_set_exception_instance (error,
7591 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7594 /* create the wrapper, too? */
7598 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7602 prelink_method (method->method, &error);
7603 mono_error_set_pending_exception (&error);
7607 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7610 MonoClass *klass = mono_class_from_mono_type (type->type);
7612 gpointer iter = NULL;
7614 mono_class_init_checked (klass, &error);
7615 if (mono_error_set_pending_exception (&error))
7618 while ((m = mono_class_get_methods (klass, &iter))) {
7619 prelink_method (m, &error);
7620 if (mono_error_set_pending_exception (&error))
7625 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7627 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7628 gint32 const **exponents,
7629 gunichar2 const **digitLowerTable,
7630 gunichar2 const **digitUpperTable,
7631 gint64 const **tenPowersList,
7632 gint32 const **decHexDigits)
7634 *mantissas = Formatter_MantissaBitsTable;
7635 *exponents = Formatter_TensExponentTable;
7636 *digitLowerTable = Formatter_DigitLowerTable;
7637 *digitUpperTable = Formatter_DigitUpperTable;
7638 *tenPowersList = Formatter_TenPowersList;
7639 *decHexDigits = Formatter_DecHexDigits;
7643 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7644 * and avoid useless allocations.
7647 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7649 MonoReflectionType *rt;
7653 mono_error_init (error);
7654 for (i = 0; i < type->num_mods; ++i) {
7655 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7660 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7661 return_val_if_nok (error, NULL);
7663 for (i = 0; i < type->num_mods; ++i) {
7664 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7665 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7666 return_val_if_nok (error, NULL);
7668 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7669 return_val_if_nok (error, NULL);
7671 mono_array_setref (res, count, rt);
7678 ICALL_EXPORT MonoArray*
7679 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7682 MonoType *type = param->ClassImpl->type;
7683 MonoClass *member_class = mono_object_class (param->MemberImpl);
7684 MonoMethod *method = NULL;
7687 MonoMethodSignature *sig;
7690 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7691 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7692 method = rmethod->method;
7693 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7694 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7695 if (!(method = prop->property->get))
7696 method = prop->property->set;
7699 char *type_name = mono_type_get_full_name (member_class);
7700 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7701 MonoException *ex = mono_get_exception_not_supported (msg);
7704 mono_set_pending_exception (ex);
7708 image = method->klass->image;
7709 pos = param->PositionImpl;
7710 sig = mono_method_signature (method);
7714 type = sig->params [pos];
7716 res = type_array_from_modifiers (image, type, optional, &error);
7717 mono_error_set_pending_exception (&error);
7722 get_property_type (MonoProperty *prop)
7724 MonoMethodSignature *sig;
7726 sig = mono_method_signature (prop->get);
7728 } else if (prop->set) {
7729 sig = mono_method_signature (prop->set);
7730 return sig->params [sig->param_count - 1];
7735 ICALL_EXPORT MonoArray*
7736 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7739 MonoType *type = get_property_type (property->property);
7740 MonoImage *image = property->klass->image;
7745 res = type_array_from_modifiers (image, type, optional, &error);
7746 mono_error_set_pending_exception (&error);
7751 *Construct a MonoType suited to be used to decode a constant blob object.
7753 * @type is the target type which will be constructed
7754 * @blob_type is the blob type, for example, that comes from the constant table
7755 * @real_type is the expected constructed type.
7758 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7760 type->type = blob_type;
7761 type->data.klass = NULL;
7762 if (blob_type == MONO_TYPE_CLASS)
7763 type->data.klass = mono_defaults.object_class;
7764 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7765 /* For enums, we need to use the base type */
7766 type->type = MONO_TYPE_VALUETYPE;
7767 type->data.klass = mono_class_from_mono_type (real_type);
7769 type->data.klass = mono_class_from_mono_type (real_type);
7772 ICALL_EXPORT MonoObject*
7773 property_info_get_default_value (MonoReflectionProperty *property)
7777 MonoProperty *prop = property->property;
7778 MonoType *type = get_property_type (prop);
7779 MonoDomain *domain = mono_object_domain (property);
7780 MonoTypeEnum def_type;
7781 const char *def_value;
7784 mono_class_init (prop->parent);
7786 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7787 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7791 def_value = mono_class_get_property_default_value (prop, &def_type);
7793 mono_type_from_blob_type (&blob_type, def_type, type);
7794 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7796 mono_error_set_pending_exception (&error);
7800 ICALL_EXPORT MonoBoolean
7801 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7804 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7805 MonoCustomAttrInfo *cinfo;
7808 mono_class_init_checked (attr_class, &error);
7809 if (mono_error_set_pending_exception (&error))
7812 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7813 if (!is_ok (&error)) {
7814 mono_error_set_pending_exception (&error);
7819 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7821 mono_custom_attrs_free (cinfo);
7825 ICALL_EXPORT MonoArray*
7826 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7828 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7833 mono_class_init_checked (attr_class, &error);
7834 if (mono_error_set_pending_exception (&error))
7838 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7839 if (!mono_error_ok (&error)) {
7840 mono_error_set_pending_exception (&error);
7847 ICALL_EXPORT MonoArray*
7848 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7852 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7853 mono_error_set_pending_exception (&error);
7858 ICALL_EXPORT MonoStringHandle
7859 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7862 MonoStringHandle display_name;
7864 mono_error_init (error);
7865 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7866 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7868 return display_name;
7872 static inline gint32
7873 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7875 return WAIT_TIMEOUT;
7877 #endif /* !HOST_WIN32 */
7880 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7882 return mono_icall_wait_for_input_idle (handle, milliseconds);
7886 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7888 return mono_process_current_pid ();
7891 ICALL_EXPORT MonoBoolean
7892 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7904 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7906 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7910 ICALL_EXPORT MonoObject*
7911 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7913 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7918 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7920 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7924 ICALL_EXPORT MonoObject*
7925 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7927 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7931 ICALL_EXPORT MonoBoolean
7932 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7934 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7939 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7941 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7945 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7947 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7952 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7954 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7958 ICALL_EXPORT mono_unichar2*
7959 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7961 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7968 #ifndef DISABLE_ICALL_TABLES
7970 #define ICALL_TYPE(id,name,first)
7971 #define ICALL(id,name,func) Icall_ ## id,
7972 #define HANDLES(inner) inner
7975 #include "metadata/icall-def.h"
7981 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7982 #define ICALL(id,name,func)
7984 #define HANDLES(inner) inner
7986 #include "metadata/icall-def.h"
7992 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7993 #define ICALL(id,name,func)
7995 #define HANDLES(inner) inner
7997 guint16 first_icall;
8000 static const IcallTypeDesc
8001 icall_type_descs [] = {
8002 #include "metadata/icall-def.h"
8006 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8009 #define HANDLES(inner) inner
8011 #define ICALL_TYPE(id,name,first)
8014 #ifdef HAVE_ARRAY_ELEM_INIT
8015 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8016 #define MSGSTRFIELD1(line) str##line
8018 static const struct msgstrtn_t {
8019 #define ICALL(id,name,func)
8021 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8022 #include "metadata/icall-def.h"
8024 } icall_type_names_str = {
8025 #define ICALL_TYPE(id,name,first) (name),
8026 #include "metadata/icall-def.h"
8029 static const guint16 icall_type_names_idx [] = {
8030 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8031 #include "metadata/icall-def.h"
8034 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8036 static const struct msgstr_t {
8038 #define ICALL_TYPE(id,name,first)
8039 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8040 #include "metadata/icall-def.h"
8042 } icall_names_str = {
8043 #define ICALL(id,name,func) (name),
8044 #include "metadata/icall-def.h"
8047 static const guint16 icall_names_idx [] = {
8048 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8049 #include "metadata/icall-def.h"
8052 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8058 #define ICALL_TYPE(id,name,first) name,
8059 #define ICALL(id,name,func)
8060 static const char* const
8061 icall_type_names [] = {
8062 #include "metadata/icall-def.h"
8066 #define icall_type_name_get(id) (icall_type_names [(id)])
8070 #define ICALL_TYPE(id,name,first)
8071 #define ICALL(id,name,func) name,
8072 static const char* const
8074 #include "metadata/icall-def.h"
8077 #define icall_name_get(id) icall_names [(id)]
8079 #endif /* !HAVE_ARRAY_ELEM_INIT */
8082 #define HANDLES(inner) inner
8085 #define ICALL_TYPE(id,name,first)
8086 #define ICALL(id,name,func) func,
8087 static const gconstpointer
8088 icall_functions [] = {
8089 #include "metadata/icall-def.h"
8093 #ifdef ENABLE_ICALL_SYMBOL_MAP
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_symbols [] = {
8102 #include "metadata/icall-def.h"
8109 #define ICALL_TYPE(id,name,first)
8110 #define ICALL(id,name,func) 0,
8112 #define HANDLES(inner) 1,
8114 icall_uses_handles [] = {
8115 #include "metadata/icall-def.h"
8120 #endif /* DISABLE_ICALL_TABLES */
8122 static mono_mutex_t icall_mutex;
8123 static GHashTable *icall_hash = NULL;
8124 static GHashTable *jit_icall_hash_name = NULL;
8125 static GHashTable *jit_icall_hash_addr = NULL;
8128 mono_icall_init (void)
8130 #ifndef DISABLE_ICALL_TABLES
8133 /* check that tables are sorted: disable in release */
8136 const char *prev_class = NULL;
8137 const char *prev_method;
8139 for (i = 0; i < Icall_type_num; ++i) {
8140 const IcallTypeDesc *desc;
8143 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8144 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8145 prev_class = icall_type_name_get (i);
8146 desc = &icall_type_descs [i];
8147 num_icalls = icall_desc_num_icalls (desc);
8148 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8149 for (j = 0; j < num_icalls; ++j) {
8150 const char *methodn = icall_name_get (desc->first_icall + j);
8151 if (prev_method && strcmp (prev_method, methodn) >= 0)
8152 g_print ("method %s should come before method %s\n", methodn, prev_method);
8153 prev_method = methodn;
8159 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8160 mono_os_mutex_init (&icall_mutex);
8164 mono_icall_lock (void)
8166 mono_locks_os_acquire (&icall_mutex, IcallLock);
8170 mono_icall_unlock (void)
8172 mono_locks_os_release (&icall_mutex, IcallLock);
8176 mono_icall_cleanup (void)
8178 g_hash_table_destroy (icall_hash);
8179 g_hash_table_destroy (jit_icall_hash_name);
8180 g_hash_table_destroy (jit_icall_hash_addr);
8181 mono_os_mutex_destroy (&icall_mutex);
8185 * mono_add_internal_call:
8186 * @name: method specification to surface to the managed world
8187 * @method: pointer to a C method to invoke when the method is called
8189 * This method surfaces the C function pointed by @method as a method
8190 * that has been surfaced in managed code with the method specified in
8191 * @name as an internal call.
8193 * Internal calls are surfaced to all app domains loaded and they are
8194 * accessibly by a type with the specified name.
8196 * You must provide a fully qualified type name, that is namespaces
8197 * and type name, followed by a colon and the method name, with an
8198 * optional signature to bind.
8200 * For example, the following are all valid declarations:
8202 * "MyApp.Services.ScriptService:Accelerate"
8203 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8205 * You use method parameters in cases where there might be more than
8206 * one surface method to managed code. That way you can register different
8207 * internal calls for different method overloads.
8209 * The internal calls are invoked with no marshalling. This means that .NET
8210 * types like System.String are exposed as `MonoString *` parameters. This is
8211 * different than the way that strings are surfaced in P/Invoke.
8213 * For more information on how the parameters are marshalled, see the
8214 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8217 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8218 * reference for more information on the format of method descriptions.
8221 mono_add_internal_call (const char *name, gconstpointer method)
8225 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8227 mono_icall_unlock ();
8230 #ifndef DISABLE_ICALL_TABLES
8232 #ifdef HAVE_ARRAY_ELEM_INIT
8234 compare_method_imap (const void *key, const void *elem)
8236 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8237 return strcmp (key, method_name);
8241 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8243 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);
8246 return (nameslot - &icall_names_idx [0]);
8250 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8252 gsize slotnum = find_slot_icall (imap, name);
8255 return (gboolean)icall_uses_handles [slotnum];
8259 find_method_icall (const IcallTypeDesc *imap, const char *name)
8261 gsize slotnum = find_slot_icall (imap, name);
8264 return (gpointer)icall_functions [slotnum];
8268 compare_class_imap (const void *key, const void *elem)
8270 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8271 return strcmp (key, class_name);
8274 static const IcallTypeDesc*
8275 find_class_icalls (const char *name)
8277 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);
8280 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8283 #else /* HAVE_ARRAY_ELEM_INIT */
8286 compare_method_imap (const void *key, const void *elem)
8288 const char** method_name = (const char**)elem;
8289 return strcmp (key, *method_name);
8293 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8295 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8298 return nameslot - icall_names;
8302 find_method_icall (const IcallTypeDesc *imap, const char *name)
8304 gsize slotnum = find_slot_icall (imap, name);
8307 return (gpointer)icall_functions [slotnum];
8311 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8313 gsize slotnum = find_slot_icall (imap, name);
8316 return (gboolean)icall_uses_handles [slotnum];
8320 compare_class_imap (const void *key, const void *elem)
8322 const char** class_name = (const char**)elem;
8323 return strcmp (key, *class_name);
8326 static const IcallTypeDesc*
8327 find_class_icalls (const char *name)
8329 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8332 return &icall_type_descs [nameslot - icall_type_names];
8335 #endif /* HAVE_ARRAY_ELEM_INIT */
8337 #endif /* DISABLE_ICALL_TABLES */
8340 * we should probably export this as an helper (handle nested types).
8341 * Returns the number of chars written in buf.
8344 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8346 int nspacelen, cnamelen;
8347 nspacelen = strlen (klass->name_space);
8348 cnamelen = strlen (klass->name);
8349 if (nspacelen + cnamelen + 2 > bufsize)
8352 memcpy (buf, klass->name_space, nspacelen);
8353 buf [nspacelen ++] = '.';
8355 memcpy (buf + nspacelen, klass->name, cnamelen);
8356 buf [nspacelen + cnamelen] = 0;
8357 return nspacelen + cnamelen;
8360 #ifdef DISABLE_ICALL_TABLES
8362 no_icall_table (void)
8364 g_assert_not_reached ();
8369 * mono_lookup_internal_call_full:
8370 * @method: the method to look up
8371 * @uses_handles: out argument if method needs handles around managed objects.
8373 * Returns a pointer to the icall code for the given method. If
8374 * uses_handles is not NULL, it will be set to TRUE if the method
8375 * needs managed objects wrapped using the infrastructure in handle.h
8377 * If the method is not found, warns and returns NULL.
8380 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8385 int typelen = 0, mlen, siglen;
8387 #ifndef DISABLE_ICALL_TABLES
8388 const IcallTypeDesc *imap = NULL;
8391 g_assert (method != NULL);
8393 if (method->is_inflated)
8394 method = ((MonoMethodInflated *) method)->declaring;
8396 if (method->klass->nested_in) {
8397 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8401 mname [pos++] = '/';
8404 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8410 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8415 #ifndef DISABLE_ICALL_TABLES
8416 imap = find_class_icalls (mname);
8419 mname [typelen] = ':';
8420 mname [typelen + 1] = ':';
8422 mlen = strlen (method->name);
8423 memcpy (mname + typelen + 2, method->name, mlen);
8424 sigstart = mname + typelen + 2 + mlen;
8427 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8428 siglen = strlen (tmpsig);
8429 if (typelen + mlen + siglen + 6 > sizeof (mname))
8432 memcpy (sigstart + 1, tmpsig, siglen);
8433 sigstart [siglen + 1] = ')';
8434 sigstart [siglen + 2] = 0;
8439 res = g_hash_table_lookup (icall_hash, mname);
8442 *uses_handles = FALSE;
8443 mono_icall_unlock ();;
8446 /* try without signature */
8448 res = g_hash_table_lookup (icall_hash, mname);
8451 *uses_handles = FALSE;
8452 mono_icall_unlock ();
8456 #ifdef DISABLE_ICALL_TABLES
8457 mono_icall_unlock ();
8458 /* Fail only when the result is actually used */
8459 /* mono_marshal_get_native_wrapper () depends on this */
8460 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8461 return ves_icall_System_String_ctor_RedirectToCreateString;
8463 return no_icall_table;
8465 /* it wasn't found in the static call tables */
8468 *uses_handles = FALSE;
8469 mono_icall_unlock ();
8472 res = find_method_icall (imap, sigstart - mlen);
8475 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8476 mono_icall_unlock ();
8479 /* try _with_ signature */
8481 res = find_method_icall (imap, sigstart - mlen);
8484 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8485 mono_icall_unlock ();
8489 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8490 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8491 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8492 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8493 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");
8494 g_print ("If you see other errors or faults after this message they are probably related\n");
8495 g_print ("and you need to fix your mono install first.\n");
8497 mono_icall_unlock ();
8504 mono_lookup_internal_call (MonoMethod *method)
8506 return mono_lookup_internal_call_full (method, NULL);
8509 #ifdef ENABLE_ICALL_SYMBOL_MAP
8511 func_cmp (gconstpointer key, gconstpointer p)
8513 return (gsize)key - (gsize)*(gsize*)p;
8518 * mono_lookup_icall_symbol:
8520 * Given the icall METHOD, returns its C symbol.
8523 mono_lookup_icall_symbol (MonoMethod *m)
8525 #ifdef DISABLE_ICALL_TABLES
8526 g_assert_not_reached ();
8529 #ifdef ENABLE_ICALL_SYMBOL_MAP
8533 static gconstpointer *functions_sorted;
8534 static const char**symbols_sorted;
8535 static gboolean inited;
8540 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8541 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8542 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8543 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8544 /* Bubble sort the two arrays */
8548 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8549 if (functions_sorted [i] > functions_sorted [i + 1]) {
8552 tmp = functions_sorted [i];
8553 functions_sorted [i] = functions_sorted [i + 1];
8554 functions_sorted [i + 1] = tmp;
8555 tmp = symbols_sorted [i];
8556 symbols_sorted [i] = symbols_sorted [i + 1];
8557 symbols_sorted [i + 1] = tmp;
8564 func = mono_lookup_internal_call (m);
8567 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8571 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8573 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8574 g_assert_not_reached ();
8581 type_from_typename (char *type_name)
8583 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8585 if (!strcmp (type_name, "int"))
8586 klass = mono_defaults.int_class;
8587 else if (!strcmp (type_name, "ptr"))
8588 klass = mono_defaults.int_class;
8589 else if (!strcmp (type_name, "void"))
8590 klass = mono_defaults.void_class;
8591 else if (!strcmp (type_name, "int32"))
8592 klass = mono_defaults.int32_class;
8593 else if (!strcmp (type_name, "uint32"))
8594 klass = mono_defaults.uint32_class;
8595 else if (!strcmp (type_name, "int8"))
8596 klass = mono_defaults.sbyte_class;
8597 else if (!strcmp (type_name, "uint8"))
8598 klass = mono_defaults.byte_class;
8599 else if (!strcmp (type_name, "int16"))
8600 klass = mono_defaults.int16_class;
8601 else if (!strcmp (type_name, "uint16"))
8602 klass = mono_defaults.uint16_class;
8603 else if (!strcmp (type_name, "long"))
8604 klass = mono_defaults.int64_class;
8605 else if (!strcmp (type_name, "ulong"))
8606 klass = mono_defaults.uint64_class;
8607 else if (!strcmp (type_name, "float"))
8608 klass = mono_defaults.single_class;
8609 else if (!strcmp (type_name, "double"))
8610 klass = mono_defaults.double_class;
8611 else if (!strcmp (type_name, "object"))
8612 klass = mono_defaults.object_class;
8613 else if (!strcmp (type_name, "obj"))
8614 klass = mono_defaults.object_class;
8615 else if (!strcmp (type_name, "string"))
8616 klass = mono_defaults.string_class;
8617 else if (!strcmp (type_name, "bool"))
8618 klass = mono_defaults.boolean_class;
8619 else if (!strcmp (type_name, "boolean"))
8620 klass = mono_defaults.boolean_class;
8622 g_error ("%s", type_name);
8623 g_assert_not_reached ();
8625 return &klass->byval_arg;
8629 * LOCKING: Take the corlib image lock.
8631 MonoMethodSignature*
8632 mono_create_icall_signature (const char *sigstr)
8637 MonoMethodSignature *res, *res2;
8638 MonoImage *corlib = mono_defaults.corlib;
8640 mono_image_lock (corlib);
8641 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8642 mono_image_unlock (corlib);
8647 parts = g_strsplit (sigstr, " ", 256);
8656 res = mono_metadata_signature_alloc (corlib, len - 1);
8661 * Under windows, the default pinvoke calling convention is STDCALL but
8664 res->call_convention = MONO_CALL_C;
8667 res->ret = type_from_typename (parts [0]);
8668 for (i = 1; i < len; ++i) {
8669 res->params [i - 1] = type_from_typename (parts [i]);
8674 mono_image_lock (corlib);
8675 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8677 res = res2; /*Value is allocated in the image pool*/
8679 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8680 mono_image_unlock (corlib);
8686 mono_find_jit_icall_by_name (const char *name)
8688 MonoJitICallInfo *info;
8689 g_assert (jit_icall_hash_name);
8692 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8693 mono_icall_unlock ();
8698 mono_find_jit_icall_by_addr (gconstpointer addr)
8700 MonoJitICallInfo *info;
8701 g_assert (jit_icall_hash_addr);
8704 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8705 mono_icall_unlock ();
8711 * mono_get_jit_icall_info:
8713 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8714 * caller should access it while holding the icall lock.
8717 mono_get_jit_icall_info (void)
8719 return jit_icall_hash_name;
8723 * mono_lookup_jit_icall_symbol:
8725 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8728 mono_lookup_jit_icall_symbol (const char *name)
8730 MonoJitICallInfo *info;
8731 const char *res = NULL;
8734 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8736 res = info->c_symbol;
8737 mono_icall_unlock ();
8742 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8745 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8746 mono_icall_unlock ();
8750 * 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
8751 * icalls without wrappers in some cases.
8754 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8756 MonoJitICallInfo *info;
8763 if (!jit_icall_hash_name) {
8764 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8765 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8768 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8769 g_warning ("jit icall already defined \"%s\"\n", name);
8770 g_assert_not_reached ();
8773 info = g_new0 (MonoJitICallInfo, 1);
8778 info->c_symbol = c_symbol;
8779 info->no_raise = no_raise;
8782 info->wrapper = func;
8784 info->wrapper = NULL;
8787 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8788 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8790 mono_icall_unlock ();
8795 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8797 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);