5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool-ms.h>
40 #include <mono/metadata/threadpool-ms-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/domain-internals.h>
56 #include <mono/metadata/metadata-internals.h>
57 #include <mono/metadata/class-internals.h>
58 #include <mono/metadata/reflection-internals.h>
59 #include <mono/metadata/marshal.h>
60 #include <mono/metadata/gc-internals.h>
61 #include <mono/metadata/mono-gc.h>
62 #include <mono/metadata/rand.h>
63 #include <mono/metadata/sysmath.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array, MonoClassField *field_handle, MonoError *error)
846 mono_error_init (error);
848 MonoClass *klass = mono_handle_class (array);
849 guint32 size = mono_array_element_size (klass);
850 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
852 const char *field_data;
854 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
855 mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type");
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 mono_error_set_argument (error, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle));
864 size *= MONO_HANDLE_GETVAL(array, max_length);
865 field_data = mono_field_get_data (field_handle);
867 if (size > mono_type_size (field_handle->type, &align)) {
868 mono_error_set_argument (error, "field_handle", "Field not large enough to fill array");
872 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
874 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
875 guint ## n *src = (guint ## n *) field_data; \
877 nEnt = (size / sizeof(guint ## n)); \
879 for (i = 0; i < nEnt; i++) { \
880 data[i] = read ## n (&src[i]); \
884 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
886 switch (type->type) {
903 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
907 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
912 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
914 return offsetof (MonoString, chars);
917 ICALL_EXPORT MonoObject *
918 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
920 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
924 MonoObject *ret = mono_object_clone_checked (obj, &error);
925 mono_error_set_pending_exception (&error);
932 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
938 MONO_CHECK_ARG_NULL (handle,);
940 klass = mono_class_from_mono_type (handle);
941 MONO_CHECK_ARG (handle, klass,);
943 if (mono_class_is_gtd (klass))
946 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
947 if (!is_ok (&error)) {
948 mono_error_set_pending_exception (&error);
952 /* This will call the type constructor */
953 if (!mono_runtime_class_init_full (vtable, &error))
954 mono_error_set_pending_exception (&error);
958 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
962 mono_image_check_for_module_cctor (image);
963 if (image->has_module_cctor) {
964 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
965 if (!mono_error_ok (&error)) {
966 mono_error_set_pending_exception (&error);
969 /*It's fine to raise the exception here*/
970 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
971 if (!is_ok (&error)) {
972 mono_error_set_pending_exception (&error);
975 if (!mono_runtime_class_init_full (vtable, &error))
976 mono_error_set_pending_exception (&error);
980 ICALL_EXPORT MonoBoolean
981 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
983 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
984 // It does not work on win32
990 MonoInternalThread *thread;
992 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
993 /* if we have no info we are optimistic and assume there is enough room */
997 thread = mono_thread_internal_current ();
998 // .net seems to check that at least 50% of stack is available
999 min_size = thread->stack_size / 2;
1001 current = (guint8 *)&stack_addr;
1002 if (current > stack_addr) {
1003 if ((current - stack_addr) < min_size)
1006 if (current - (stack_addr - stack_size) < min_size)
1013 ICALL_EXPORT MonoObject *
1014 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1017 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1018 mono_error_set_pending_exception (&error);
1024 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1028 MonoObject **values = NULL;
1031 gint32 result = (int)(gsize)mono_defaults.int32_class;
1032 MonoClassField* field;
1035 klass = mono_object_class (this_obj);
1037 if (mono_class_num_fields (klass) == 0)
1041 * Compute the starting value of the hashcode for fields of primitive
1042 * types, and return the remaining fields in an array to the managed side.
1043 * This way, we can avoid costly reflection operations in managed code.
1046 while ((field = mono_class_get_fields (klass, &iter))) {
1047 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1049 if (mono_field_is_deleted (field))
1051 /* FIXME: Add more types */
1052 switch (field->type->type) {
1054 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1056 case MONO_TYPE_STRING: {
1058 s = *(MonoString**)((guint8*)this_obj + field->offset);
1060 result ^= mono_string_hash (s);
1065 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1066 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1067 if (!is_ok (&error)) {
1068 mono_error_set_pending_exception (&error);
1071 values [count++] = o;
1077 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1078 if (mono_error_set_pending_exception (&error))
1080 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1081 for (i = 0; i < count; ++i)
1082 mono_array_setref (*fields, i, values [i]);
1089 ICALL_EXPORT MonoBoolean
1090 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1094 MonoObject **values = NULL;
1096 MonoClassField* field;
1100 MONO_CHECK_ARG_NULL (that, FALSE);
1102 if (this_obj->vtable != that->vtable)
1105 klass = mono_object_class (this_obj);
1107 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1108 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1111 * Do the comparison for fields of primitive type and return a result if
1112 * possible. Otherwise, return the remaining fields in an array to the
1113 * managed side. This way, we can avoid costly reflection operations in
1118 while ((field = mono_class_get_fields (klass, &iter))) {
1119 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1121 if (mono_field_is_deleted (field))
1123 /* FIXME: Add more types */
1124 switch (field->type->type) {
1127 case MONO_TYPE_BOOLEAN:
1128 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1133 case MONO_TYPE_CHAR:
1134 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1139 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1144 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1148 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1152 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1157 case MONO_TYPE_STRING: {
1158 MonoString *s1, *s2;
1159 guint32 s1len, s2len;
1160 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1161 s2 = *(MonoString**)((guint8*)that + field->offset);
1164 if ((s1 == NULL) || (s2 == NULL))
1166 s1len = mono_string_length (s1);
1167 s2len = mono_string_length (s2);
1171 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1177 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1178 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1179 if (!is_ok (&error)) {
1180 mono_error_set_pending_exception (&error);
1183 values [count++] = o;
1184 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1185 if (!is_ok (&error)) {
1186 mono_error_set_pending_exception (&error);
1189 values [count++] = o;
1192 if (klass->enumtype)
1193 /* enums only have one non-static field */
1199 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1200 if (mono_error_set_pending_exception (&error))
1202 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1203 for (i = 0; i < count; ++i)
1204 mono_array_setref_fast (*fields, i, values [i]);
1211 ICALL_EXPORT MonoReflectionType *
1212 ves_icall_System_Object_GetType (MonoObject *obj)
1215 MonoReflectionType *ret;
1216 #ifndef DISABLE_REMOTING
1217 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1218 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1221 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1223 mono_error_set_pending_exception (&error);
1228 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1230 MonoMethod **dest = (MonoMethod **)data;
1232 /* skip unmanaged frames */
1237 if (!strcmp (m->klass->name_space, "System.Reflection"))
1246 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1248 MonoMethod **dest = (MonoMethod **)data;
1250 /* skip unmanaged frames */
1254 if (m->wrapper_type != MONO_WRAPPER_NONE)
1262 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1273 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1275 MonoMethod **dest = (MonoMethod **)data;
1277 /* skip unmanaged frames */
1281 if (m->wrapper_type != MONO_WRAPPER_NONE)
1289 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1290 || (!strcmp (m->klass->name_space, "System"))))
1300 static MonoReflectionType *
1301 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1303 MonoMethod *m, *dest;
1305 MonoType *type = NULL;
1306 MonoAssembly *assembly = NULL;
1307 gboolean type_resolve = FALSE;
1308 MonoImage *rootimage = NULL;
1310 mono_error_init (error);
1313 * We must compute the calling assembly as type loading must happen under a metadata context.
1314 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1315 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1317 m = mono_method_get_last_managed ();
1319 if (m && m->klass->image != mono_defaults.corlib) {
1320 /* Happens with inlining */
1322 /* Ugly hack: type_from_parsed_name is called from
1323 * System.Type.internal_from_name, which is called most
1324 * directly from System.Type.GetType(string,bool,bool) but
1325 * also indirectly from places such as
1326 * System.Type.GetType(string,func,func) (via
1327 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1328 * so we need to skip over all of those to find the true caller.
1330 * It would be nice if we had stack marks.
1332 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1338 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1339 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1340 * to crash. This only seems to happen in some strange remoting
1341 * scenarios and I was unable to figure out what's happening there.
1342 * Dec 10, 2005 - Martin.
1346 assembly = dest->klass->image->assembly;
1347 type_resolve = TRUE;
1348 rootimage = assembly->image;
1350 g_warning (G_STRLOC);
1352 *caller_assembly = assembly;
1354 if (info->assembly.name)
1355 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1358 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1359 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1360 return_val_if_nok (error, NULL);
1364 // Say we're looking for System.Generic.Dict<int, Local>
1365 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1366 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1367 // is messed up when we go to construct the Local as the type arg...
1369 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1370 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1371 if (!info->assembly.name && !type) {
1373 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1374 return_val_if_nok (error, NULL);
1376 if (assembly && !type && type_resolve) {
1377 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1378 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1379 return_val_if_nok (error, NULL);
1385 return mono_type_get_object_checked (mono_domain_get (), type, error);
1388 ICALL_EXPORT MonoReflectionType*
1389 ves_icall_System_Type_internal_from_name (MonoString *name,
1390 MonoBoolean throwOnError,
1391 MonoBoolean ignoreCase)
1394 MonoTypeNameParse info;
1395 MonoReflectionType *type = NULL;
1397 MonoAssembly *caller_assembly;
1399 char *str = mono_string_to_utf8_checked (name, &error);
1400 if (!is_ok (&error))
1403 parsedOk = mono_reflection_parse_type (str, &info);
1405 /* mono_reflection_parse_type() mangles the string */
1407 mono_reflection_free_type_info (&info);
1409 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1413 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1415 if (!is_ok (&error)) {
1416 mono_reflection_free_type_info (&info);
1422 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1424 if (info.assembly.name)
1425 aname = mono_stringify_assembly_name (&info.assembly);
1426 else if (caller_assembly)
1427 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1429 aname = g_strdup ("");
1430 mono_error_set_type_load_name (&error, tname, aname, "");
1432 mono_reflection_free_type_info (&info);
1438 if (!is_ok (&error)) {
1440 mono_error_set_pending_exception (&error);
1442 mono_error_cleanup (&error);
1450 ICALL_EXPORT MonoReflectionType*
1451 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1454 MonoReflectionType *ret;
1455 MonoDomain *domain = mono_domain_get ();
1457 ret = mono_type_get_object_checked (domain, handle, &error);
1458 mono_error_set_pending_exception (&error);
1463 ICALL_EXPORT MonoType*
1464 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1466 return mono_class_get_type (klass);
1470 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1472 g_ptr_array_free (ptr_array, TRUE);
1476 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1482 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1485 char *res = mono_string_to_utf8_checked (s, &error);
1486 mono_error_set_pending_exception (&error);
1490 /* System.TypeCode */
1509 TYPECODE_STRING = 18
1512 ICALL_EXPORT guint32
1513 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1515 int t = type->type->type;
1517 if (type->type->byref)
1518 return TYPECODE_OBJECT;
1522 case MONO_TYPE_VOID:
1523 return TYPECODE_OBJECT;
1524 case MONO_TYPE_BOOLEAN:
1525 return TYPECODE_BOOLEAN;
1527 return TYPECODE_BYTE;
1529 return TYPECODE_SBYTE;
1531 return TYPECODE_UINT16;
1533 return TYPECODE_INT16;
1534 case MONO_TYPE_CHAR:
1535 return TYPECODE_CHAR;
1539 return TYPECODE_OBJECT;
1541 return TYPECODE_UINT32;
1543 return TYPECODE_INT32;
1545 return TYPECODE_UINT64;
1547 return TYPECODE_INT64;
1549 return TYPECODE_SINGLE;
1551 return TYPECODE_DOUBLE;
1552 case MONO_TYPE_VALUETYPE: {
1553 MonoClass *klass = type->type->data.klass;
1555 if (klass->enumtype) {
1556 t = mono_class_enum_basetype (klass)->type;
1558 } else if (mono_is_corlib_image (klass->image)) {
1559 if (strcmp (klass->name_space, "System") == 0) {
1560 if (strcmp (klass->name, "Decimal") == 0)
1561 return TYPECODE_DECIMAL;
1562 else if (strcmp (klass->name, "DateTime") == 0)
1563 return TYPECODE_DATETIME;
1566 return TYPECODE_OBJECT;
1568 case MONO_TYPE_STRING:
1569 return TYPECODE_STRING;
1570 case MONO_TYPE_SZARRAY:
1571 case MONO_TYPE_ARRAY:
1572 case MONO_TYPE_OBJECT:
1574 case MONO_TYPE_MVAR:
1575 case MONO_TYPE_TYPEDBYREF:
1576 return TYPECODE_OBJECT;
1577 case MONO_TYPE_CLASS:
1579 MonoClass *klass = type->type->data.klass;
1580 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1581 if (strcmp (klass->name, "DBNull") == 0)
1582 return TYPECODE_DBNULL;
1585 return TYPECODE_OBJECT;
1586 case MONO_TYPE_GENERICINST:
1587 return TYPECODE_OBJECT;
1589 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1595 mono_type_is_primitive (MonoType *type)
1597 return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
1598 type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
1602 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1604 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1605 return mono_class_enum_basetype (type->data.klass);
1606 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1607 return mono_class_enum_basetype (type->data.generic_class->container_class);
1611 ICALL_EXPORT guint32
1612 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1617 g_assert (type != NULL);
1619 klass = mono_class_from_mono_type (type->type);
1620 klassc = mono_class_from_mono_type (c->type);
1622 if (type->type->byref ^ c->type->byref)
1625 if (type->type->byref) {
1626 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1627 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1629 klass = mono_class_from_mono_type (t);
1630 klassc = mono_class_from_mono_type (ot);
1632 if (mono_type_is_primitive (t)) {
1633 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1634 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1635 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1636 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1637 return t->type == ot->type;
1639 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1642 if (klass->valuetype)
1643 return klass == klassc;
1644 return klass->valuetype == klassc->valuetype;
1647 return mono_class_is_assignable_from (klass, klassc);
1650 ICALL_EXPORT guint32
1651 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1654 MonoClass *klass = mono_class_from_mono_type (type->type);
1655 mono_class_init_checked (klass, &error);
1656 if (!is_ok (&error)) {
1657 mono_error_set_pending_exception (&error);
1660 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1661 mono_error_set_pending_exception (&error);
1665 ICALL_EXPORT guint32
1666 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1668 MonoClass *klass = mono_class_from_mono_type (type->type);
1669 return mono_class_get_flags (klass);
1672 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1673 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1676 MonoClass *klass = field->field->parent;
1677 MonoMarshalType *info;
1681 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1682 if (mono_class_is_gtd (klass) ||
1683 (gklass && gklass->context.class_inst->is_open))
1686 ftype = mono_field_get_type (field->field);
1687 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1690 info = mono_marshal_load_type_info (klass);
1692 for (i = 0; i < info->num_fields; ++i) {
1693 if (info->fields [i].field == field->field) {
1694 if (!info->fields [i].mspec)
1697 MonoReflectionMarshalAsAttribute* obj;
1698 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1699 if (!mono_error_ok (&error))
1700 mono_error_set_pending_exception (&error);
1709 ICALL_EXPORT MonoReflectionField*
1710 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1713 gboolean found = FALSE;
1719 klass = handle->parent;
1721 klass = mono_class_from_mono_type (type);
1723 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1726 /* The managed code will throw the exception */
1730 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1731 mono_error_set_pending_exception (&error);
1735 ICALL_EXPORT MonoReflectionEvent*
1736 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1744 klass = handle->parent;
1746 klass = mono_class_from_mono_type (type);
1748 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1750 /* Managed code will throw an exception */
1754 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1755 mono_error_set_pending_exception (&error);
1760 ICALL_EXPORT MonoReflectionProperty*
1761 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1769 klass = handle->parent;
1771 klass = mono_class_from_mono_type (type);
1773 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1775 /* Managed code will throw an exception */
1779 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1780 mono_error_set_pending_exception (&error);
1784 ICALL_EXPORT MonoArray*
1785 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1788 MonoType *type = mono_field_get_type_checked (field->field, &error);
1791 if (!mono_error_ok (&error)) {
1792 mono_error_set_pending_exception (&error);
1796 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1797 mono_error_set_pending_exception (&error);
1802 vell_icall_get_method_attributes (MonoMethod *method)
1804 return method->flags;
1808 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1811 MonoReflectionType *rt;
1812 MonoDomain *domain = mono_domain_get ();
1813 MonoMethodSignature* sig;
1815 sig = mono_method_signature_checked (method, &error);
1816 if (!mono_error_ok (&error)) {
1817 mono_error_set_pending_exception (&error);
1821 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1822 if (!mono_error_ok (&error)) {
1823 mono_error_set_pending_exception (&error);
1827 MONO_STRUCT_SETREF (info, parent, rt);
1829 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1830 if (!mono_error_ok (&error)) {
1831 mono_error_set_pending_exception (&error);
1835 MONO_STRUCT_SETREF (info, ret, rt);
1837 info->attrs = method->flags;
1838 info->implattrs = method->iflags;
1839 if (sig->call_convention == MONO_CALL_DEFAULT)
1840 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1842 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1847 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1850 ICALL_EXPORT MonoArray*
1851 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1854 MonoDomain *domain = mono_domain_get ();
1856 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1857 mono_error_set_pending_exception (&error);
1861 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1862 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1865 MonoDomain *domain = mono_domain_get ();
1866 MonoReflectionMarshalAsAttribute* res = NULL;
1867 MonoMarshalSpec **mspecs;
1870 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1871 mono_method_get_marshal_info (method, mspecs);
1874 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1875 if (!mono_error_ok (&error)) {
1876 mono_error_set_pending_exception (&error);
1881 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1883 mono_metadata_free_marshal_spec (mspecs [i]);
1890 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1892 MonoClass *parent = field->field->parent;
1893 mono_class_setup_fields (parent);
1895 return field->field->offset - sizeof (MonoObject);
1898 ICALL_EXPORT MonoReflectionType*
1899 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1902 MonoReflectionType *ret;
1905 parent = declaring? field->field->parent: field->klass;
1907 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1908 mono_error_set_pending_exception (&error);
1914 ICALL_EXPORT MonoObject *
1915 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1918 MonoClass *fklass = field->klass;
1919 MonoClassField *cf = field->field;
1920 MonoDomain *domain = mono_object_domain (field);
1922 if (fklass->image->assembly->ref_only) {
1923 mono_set_pending_exception (mono_get_exception_invalid_operation (
1924 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1928 if (mono_security_core_clr_enabled () &&
1929 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1930 mono_error_set_pending_exception (&error);
1934 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1935 mono_error_set_pending_exception (&error);
1940 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1943 MonoClassField *cf = field->field;
1947 if (field->klass->image->assembly->ref_only) {
1948 mono_set_pending_exception (mono_get_exception_invalid_operation (
1949 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1953 if (mono_security_core_clr_enabled () &&
1954 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1955 mono_error_set_pending_exception (&error);
1959 type = mono_field_get_type_checked (cf, &error);
1960 if (!mono_error_ok (&error)) {
1961 mono_error_set_pending_exception (&error);
1965 v = (gchar *) value;
1967 switch (type->type) {
1970 case MONO_TYPE_BOOLEAN:
1973 case MONO_TYPE_CHAR:
1982 case MONO_TYPE_VALUETYPE:
1985 v += sizeof (MonoObject);
1987 case MONO_TYPE_STRING:
1988 case MONO_TYPE_OBJECT:
1989 case MONO_TYPE_CLASS:
1990 case MONO_TYPE_ARRAY:
1991 case MONO_TYPE_SZARRAY:
1994 case MONO_TYPE_GENERICINST: {
1995 MonoGenericClass *gclass = type->data.generic_class;
1996 g_assert (!gclass->context.class_inst->is_open);
1998 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1999 MonoClass *nklass = mono_class_from_mono_type (type);
2000 MonoObject *nullable;
2003 * Convert the boxed vtype into a Nullable structure.
2004 * This is complicated by the fact that Nullables have
2005 * a variable structure.
2007 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2008 if (!mono_error_ok (&error)) {
2009 mono_error_set_pending_exception (&error);
2013 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2015 v = (gchar *)mono_object_unbox (nullable);
2018 if (gclass->container_class->valuetype && (v != NULL))
2019 v += sizeof (MonoObject);
2023 g_error ("type 0x%x not handled in "
2024 "ves_icall_FieldInfo_SetValueInternal", type->type);
2029 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2030 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2031 if (!is_ok (&error)) {
2032 mono_error_set_pending_exception (&error);
2035 if (!vtable->initialized) {
2036 if (!mono_runtime_class_init_full (vtable, &error)) {
2037 mono_error_set_pending_exception (&error);
2041 mono_field_static_set_value (vtable, cf, v);
2043 mono_field_set_value (obj, cf, v);
2048 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2057 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2058 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2062 if (MONO_TYPE_IS_REFERENCE (f->type))
2063 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2065 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2068 ICALL_EXPORT MonoObject *
2069 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2071 MonoObject *o = NULL;
2072 MonoClassField *field = rfield->field;
2074 MonoDomain *domain = mono_object_domain (rfield);
2076 MonoTypeEnum def_type;
2077 const char *def_value;
2081 mono_class_init (field->parent);
2083 t = mono_field_get_type_checked (field, &error);
2084 if (!mono_error_ok (&error)) {
2085 mono_error_set_pending_exception (&error);
2089 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2090 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2094 if (image_is_dynamic (field->parent->image)) {
2095 MonoClass *klass = field->parent;
2096 int fidx = field - klass->fields;
2097 MonoClassExt *ext = mono_class_get_ext (klass);
2100 g_assert (ext->field_def_values);
2101 def_type = ext->field_def_values [fidx].def_type;
2102 def_value = ext->field_def_values [fidx].data;
2104 if (def_type == MONO_TYPE_END) {
2105 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2109 def_value = mono_class_get_field_default_value (field, &def_type);
2110 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2112 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2117 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2121 case MONO_TYPE_BOOLEAN:
2124 case MONO_TYPE_CHAR:
2132 case MONO_TYPE_R8: {
2135 /* boxed value type */
2136 t = g_new0 (MonoType, 1);
2138 klass = mono_class_from_mono_type (t);
2140 o = mono_object_new_checked (domain, klass, &error);
2141 if (!mono_error_ok (&error)) {
2142 mono_error_set_pending_exception (&error);
2145 v = ((gchar *) o) + sizeof (MonoObject);
2146 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2147 if (mono_error_set_pending_exception (&error))
2151 case MONO_TYPE_STRING:
2152 case MONO_TYPE_CLASS:
2153 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2154 if (mono_error_set_pending_exception (&error))
2158 g_assert_not_reached ();
2164 ICALL_EXPORT MonoReflectionType*
2165 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2168 MonoReflectionType *ret;
2171 type = mono_field_get_type_checked (ref_field->field, &error);
2172 if (!mono_error_ok (&error)) {
2173 mono_error_set_pending_exception (&error);
2177 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2178 if (!mono_error_ok (&error)) {
2179 mono_error_set_pending_exception (&error);
2186 /* From MonoProperty.cs */
2188 PInfo_Attributes = 1,
2189 PInfo_GetMethod = 1 << 1,
2190 PInfo_SetMethod = 1 << 2,
2191 PInfo_ReflectedType = 1 << 3,
2192 PInfo_DeclaringType = 1 << 4,
2197 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2200 MonoReflectionType *rt;
2201 MonoReflectionMethod *rm;
2202 MonoDomain *domain = mono_object_domain (property);
2203 const MonoProperty *pproperty = property->property;
2205 if ((req_info & PInfo_ReflectedType) != 0) {
2206 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2207 if (mono_error_set_pending_exception (&error))
2210 MONO_STRUCT_SETREF (info, parent, rt);
2212 if ((req_info & PInfo_DeclaringType) != 0) {
2213 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2214 if (mono_error_set_pending_exception (&error))
2217 MONO_STRUCT_SETREF (info, declaring_type, rt);
2220 if ((req_info & PInfo_Name) != 0)
2221 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2223 if ((req_info & PInfo_Attributes) != 0)
2224 info->attrs = pproperty->attrs;
2226 if ((req_info & PInfo_GetMethod) != 0) {
2227 if (pproperty->get &&
2228 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2229 pproperty->get->klass == property->klass)) {
2230 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2231 if (mono_error_set_pending_exception (&error))
2237 MONO_STRUCT_SETREF (info, get, rm);
2239 if ((req_info & PInfo_SetMethod) != 0) {
2240 if (pproperty->set &&
2241 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2242 pproperty->set->klass == property->klass)) {
2243 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2244 if (mono_error_set_pending_exception (&error))
2250 MONO_STRUCT_SETREF (info, set, rm);
2253 * There may be other methods defined for properties, though, it seems they are not exposed
2254 * in the reflection API
2259 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2262 MonoReflectionType *rt;
2263 MonoReflectionMethod *rm;
2264 MonoDomain *domain = mono_object_domain (event);
2266 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2267 if (mono_error_set_pending_exception (&error))
2270 MONO_STRUCT_SETREF (info, reflected_type, rt);
2272 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2273 if (mono_error_set_pending_exception (&error))
2276 MONO_STRUCT_SETREF (info, declaring_type, rt);
2278 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2279 info->attrs = event->event->attrs;
2281 if (event->event->add) {
2282 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2283 if (mono_error_set_pending_exception (&error))
2289 MONO_STRUCT_SETREF (info, add_method, rm);
2291 if (event->event->remove) {
2292 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2293 if (mono_error_set_pending_exception (&error))
2299 MONO_STRUCT_SETREF (info, remove_method, rm);
2301 if (event->event->raise) {
2302 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2303 if (mono_error_set_pending_exception (&error))
2309 MONO_STRUCT_SETREF (info, raise_method, rm);
2311 #ifndef MONO_SMALL_CONFIG
2312 if (event->event->other) {
2314 while (event->event->other [n])
2316 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2317 if (mono_error_set_pending_exception (&error))
2319 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2321 for (i = 0; i < n; i++) {
2322 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2323 if (mono_error_set_pending_exception (&error))
2325 mono_array_setref (info->other_methods, i, rm);
2332 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2337 mono_class_setup_interfaces (klass, error);
2338 if (!mono_error_ok (error))
2341 for (i = 0; i < klass->interface_count; i++) {
2342 ic = klass->interfaces [i];
2343 g_hash_table_insert (ifaces, ic, ic);
2345 collect_interfaces (ic, ifaces, error);
2346 if (!mono_error_ok (error))
2352 MonoArray *iface_array;
2353 MonoGenericContext *context;
2357 } FillIfaceArrayData;
2360 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2362 MonoReflectionType *rt;
2363 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2364 MonoClass *ic = (MonoClass *)key;
2365 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2367 if (!mono_error_ok (data->error))
2370 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2371 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2372 if (!mono_error_ok (data->error))
2376 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2377 if (!mono_error_ok (data->error))
2380 mono_array_setref (data->iface_array, data->next_idx++, rt);
2383 mono_metadata_free_type (inflated);
2387 get_interfaces_hash (gconstpointer v1)
2389 MonoClass *k = (MonoClass*)v1;
2391 return k->type_token;
2394 ICALL_EXPORT MonoArray*
2395 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2398 MonoClass *klass = mono_class_from_mono_type (type->type);
2400 FillIfaceArrayData data = { 0 };
2403 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2405 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2406 data.context = mono_class_get_context (klass);
2407 klass = mono_class_get_generic_class (klass)->container_class;
2410 for (parent = klass; parent; parent = parent->parent) {
2411 mono_class_setup_interfaces (parent, &error);
2412 if (!mono_error_ok (&error))
2414 collect_interfaces (parent, iface_hash, &error);
2415 if (!mono_error_ok (&error))
2419 data.error = &error;
2420 data.domain = mono_object_domain (type);
2422 len = g_hash_table_size (iface_hash);
2424 g_hash_table_destroy (iface_hash);
2425 if (!data.domain->empty_types) {
2426 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2427 if (!is_ok (&error))
2430 return data.domain->empty_types;
2433 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2434 if (!is_ok (&error))
2436 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2437 if (!mono_error_ok (&error))
2440 g_hash_table_destroy (iface_hash);
2441 return data.iface_array;
2444 g_hash_table_destroy (iface_hash);
2445 mono_error_set_pending_exception (&error);
2450 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2452 gboolean variance_used;
2453 MonoClass *klass = mono_class_from_mono_type (type->type);
2454 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2455 MonoReflectionMethod *member;
2458 int i = 0, len, ioffset;
2462 mono_class_init_checked (klass, &error);
2463 if (mono_error_set_pending_exception (&error))
2465 mono_class_init_checked (iclass, &error);
2466 if (mono_error_set_pending_exception (&error))
2469 mono_class_setup_vtable (klass);
2471 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2475 len = mono_class_num_methods (iclass);
2476 domain = mono_object_domain (type);
2477 MonoArray *targets_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 (targets, (MonoObject*) targets_arr);
2481 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2482 if (mono_error_set_pending_exception (&error))
2484 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2486 while ((method = mono_class_get_methods (iclass, &iter))) {
2487 member = mono_method_get_object_checked (domain, method, iclass, &error);
2488 if (mono_error_set_pending_exception (&error))
2490 mono_array_setref (*methods, i, member);
2491 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2492 if (mono_error_set_pending_exception (&error))
2494 mono_array_setref (*targets, i, member);
2501 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2504 MonoClass *klass = mono_class_from_mono_type (type->type);
2506 mono_class_init_checked (klass, &error);
2507 if (mono_error_set_pending_exception (&error))
2510 if (image_is_dynamic (klass->image)) {
2511 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2512 *packing = tb->packing_size;
2513 *size = tb->class_size;
2515 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2519 ICALL_EXPORT MonoReflectionType*
2520 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2523 MonoReflectionType *ret;
2526 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2527 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2528 mono_error_set_pending_exception (&error);
2532 klass = mono_class_from_mono_type (type->type);
2533 mono_class_init_checked (klass, &error);
2534 if (mono_error_set_pending_exception (&error))
2538 // GetElementType should only return a type for:
2539 // Array Pointer PassedByRef
2540 if (type->type->byref)
2541 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2542 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2543 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2544 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2545 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2549 mono_error_set_pending_exception (&error);
2554 ICALL_EXPORT MonoReflectionType*
2555 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2558 MonoReflectionType *ret;
2560 if (type->type->byref)
2563 MonoClass *klass = mono_class_from_mono_type (type->type);
2567 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2568 mono_error_set_pending_exception (&error);
2573 ICALL_EXPORT MonoBoolean
2574 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2576 return type->type->type == MONO_TYPE_PTR;
2579 ICALL_EXPORT MonoBoolean
2580 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2582 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)));
2585 ICALL_EXPORT MonoBoolean
2586 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2588 return type->type->byref;
2591 ICALL_EXPORT MonoBoolean
2592 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2595 MonoClass *klass = mono_class_from_mono_type (type->type);
2596 mono_class_init_checked (klass, &error);
2597 if (mono_error_set_pending_exception (&error))
2600 return mono_class_is_com_object (klass);
2603 ICALL_EXPORT guint32
2604 ves_icall_reflection_get_token (MonoObject* obj)
2607 guint32 result = mono_reflection_get_token_checked (obj, &error);
2608 mono_error_set_pending_exception (&error);
2612 ICALL_EXPORT MonoReflectionModule*
2613 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2616 MonoReflectionModule *result = NULL;
2617 MonoClass *klass = mono_class_from_mono_type (type->type);
2618 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2619 mono_error_set_pending_exception (&error);
2623 ICALL_EXPORT MonoReflectionAssembly*
2624 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2627 MonoDomain *domain = mono_domain_get ();
2628 MonoClass *klass = mono_class_from_mono_type (type->type);
2629 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2630 mono_error_set_pending_exception (&error);
2634 ICALL_EXPORT MonoReflectionType*
2635 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2638 MonoReflectionType *ret;
2639 MonoDomain *domain = mono_domain_get ();
2642 if (type->type->byref)
2644 if (type->type->type == MONO_TYPE_VAR) {
2645 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2646 klass = param ? param->owner.klass : NULL;
2647 } else if (type->type->type == MONO_TYPE_MVAR) {
2648 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2649 klass = param ? param->owner.method->klass : NULL;
2651 klass = mono_class_from_mono_type (type->type)->nested_in;
2657 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2658 mono_error_set_pending_exception (&error);
2663 ICALL_EXPORT MonoStringHandle
2664 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2666 MonoDomain *domain = mono_domain_get ();
2667 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2668 MonoClass *klass = mono_class_from_mono_type (type);
2671 char *n = g_strdup_printf ("%s&", klass->name);
2672 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2678 return mono_string_new_handle (domain, klass->name, error);
2682 ICALL_EXPORT MonoStringHandle
2683 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2685 MonoDomain *domain = mono_domain_get ();
2686 MonoClass *klass = mono_class_from_mono_type_handle (type);
2688 while (klass->nested_in)
2689 klass = klass->nested_in;
2691 if (klass->name_space [0] == '\0')
2692 return NULL_HANDLE_STRING;
2694 return mono_string_new_handle (domain, klass->name_space, error);
2698 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2702 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2703 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2707 klass = mono_class_from_mono_type (type->type);
2713 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2715 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2718 ICALL_EXPORT MonoArray*
2719 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2722 MonoReflectionType *rt;
2724 MonoClass *klass, *pklass;
2725 MonoDomain *domain = mono_object_domain (type);
2728 klass = mono_class_from_mono_type (type->type);
2730 if (mono_class_is_gtd (klass)) {
2731 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2732 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2733 if (mono_error_set_pending_exception (&error))
2735 for (i = 0; i < container->type_argc; ++i) {
2736 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2738 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2739 if (mono_error_set_pending_exception (&error))
2742 mono_array_setref (res, i, rt);
2744 } else if (mono_class_is_ginst (klass)) {
2745 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2746 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2747 if (mono_error_set_pending_exception (&error))
2749 for (i = 0; i < inst->type_argc; ++i) {
2750 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2751 if (mono_error_set_pending_exception (&error))
2754 mono_array_setref (res, i, rt);
2762 ICALL_EXPORT gboolean
2763 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2767 if (!IS_MONOTYPE (type))
2770 if (type->type->byref)
2773 klass = mono_class_from_mono_type (type->type);
2774 return mono_class_is_gtd (klass);
2777 ICALL_EXPORT MonoReflectionType*
2778 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2781 MonoReflectionType *ret;
2784 if (type->type->byref)
2787 klass = mono_class_from_mono_type (type->type);
2789 if (mono_class_is_gtd (klass)) {
2790 return type; /* check this one */
2792 if (mono_class_is_ginst (klass)) {
2793 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2796 tb = mono_class_get_ref_info (generic_class);
2798 if (generic_class->wastypebuilder && tb)
2799 return (MonoReflectionType *)tb;
2801 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2802 mono_error_set_pending_exception (&error);
2810 ICALL_EXPORT MonoReflectionType*
2811 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2814 MonoReflectionType *ret;
2816 MonoType *geninst, **types;
2819 g_assert (IS_MONOTYPE (type));
2820 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2821 if (mono_error_set_pending_exception (&error))
2824 count = mono_array_length (type_array);
2825 types = g_new0 (MonoType *, count);
2827 for (i = 0; i < count; i++) {
2828 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2829 types [i] = t->type;
2832 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2835 mono_error_set_pending_exception (&error);
2839 klass = mono_class_from_mono_type (geninst);
2841 /*we might inflate to the GTD*/
2842 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2843 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2847 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2848 mono_error_set_pending_exception (&error);
2853 ICALL_EXPORT gboolean
2854 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2858 if (!IS_MONOTYPE (type))
2861 if (type->type->byref)
2864 klass = mono_class_from_mono_type (type->type);
2865 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2869 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2871 if (!IS_MONOTYPE (type))
2874 if (is_generic_parameter (type->type))
2875 return mono_type_get_generic_param_num (type->type);
2879 ICALL_EXPORT MonoGenericParamInfo *
2880 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2882 return mono_generic_param_info (type->type->data.generic_param);
2885 ICALL_EXPORT MonoBoolean
2886 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2888 return is_generic_parameter (type->type);
2891 ICALL_EXPORT MonoReflectionMethod*
2892 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2893 MonoReflectionMethod* generic)
2900 MonoReflectionMethod *ret = NULL;
2902 domain = ((MonoObject *)type)->vtable->domain;
2904 klass = mono_class_from_mono_type (type->type);
2905 mono_class_init_checked (klass, &error);
2906 if (mono_error_set_pending_exception (&error))
2910 while ((method = mono_class_get_methods (klass, &iter))) {
2911 if (method->token == generic->method->token) {
2912 ret = mono_method_get_object_checked (domain, method, klass, &error);
2913 if (mono_error_set_pending_exception (&error))
2921 ICALL_EXPORT MonoReflectionMethod *
2922 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2925 MonoType *type = ref_type->type;
2927 MonoReflectionMethod *ret = NULL;
2929 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2930 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2933 if (type->type == MONO_TYPE_VAR)
2936 method = mono_type_get_generic_param_owner (type)->owner.method;
2939 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2940 if (!mono_error_ok (&error))
2941 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2945 ICALL_EXPORT MonoBoolean
2946 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2948 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2952 ICALL_EXPORT MonoBoolean
2953 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2955 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2960 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2962 MonoDomain *domain = mono_domain_get ();
2963 MonoImage *image = method->method->klass->image;
2964 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2965 MonoTableInfo *tables = image->tables;
2966 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2967 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2968 guint32 im_cols [MONO_IMPLMAP_SIZE];
2969 guint32 scope_token;
2970 const char *import = NULL;
2971 const char *scope = NULL;
2973 if (image_is_dynamic (image)) {
2974 MonoReflectionMethodAux *method_aux =
2975 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2977 import = method_aux->dllentry;
2978 scope = method_aux->dll;
2981 if (!import || !scope) {
2982 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2987 if (piinfo->implmap_idx) {
2988 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2990 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2991 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2992 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2993 scope = mono_metadata_string_heap (image, scope_token);
2997 *flags = piinfo->piflags;
2998 *entry_point = mono_string_new (domain, import);
2999 *dll_name = mono_string_new (domain, scope);
3002 ICALL_EXPORT MonoReflectionMethod *
3003 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3005 MonoMethodInflated *imethod;
3007 MonoReflectionMethod *ret = NULL;
3010 if (method->method->is_generic)
3013 if (!method->method->is_inflated)
3016 imethod = (MonoMethodInflated *) method->method;
3018 result = imethod->declaring;
3019 /* Not a generic method. */
3020 if (!result->is_generic)
3023 if (image_is_dynamic (method->method->klass->image)) {
3024 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3025 MonoReflectionMethod *res;
3028 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3029 * the dynamic case as well ?
3031 mono_image_lock ((MonoImage*)image);
3032 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3033 mono_image_unlock ((MonoImage*)image);
3039 if (imethod->context.class_inst) {
3040 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3041 /*Generic methods gets the context of the GTD.*/
3042 if (mono_class_get_context (klass)) {
3043 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3044 if (!mono_error_ok (&error))
3049 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3051 if (!mono_error_ok (&error))
3052 mono_error_set_pending_exception (&error);
3056 ICALL_EXPORT gboolean
3057 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3059 return mono_method_signature (method->method)->generic_param_count != 0;
3062 ICALL_EXPORT gboolean
3063 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3065 return method->method->is_generic;
3068 ICALL_EXPORT MonoArray*
3069 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3072 MonoReflectionType *rt;
3077 domain = mono_object_domain (method);
3079 if (method->method->is_inflated) {
3080 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3083 count = inst->type_argc;
3084 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3085 if (mono_error_set_pending_exception (&error))
3088 for (i = 0; i < count; i++) {
3089 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3090 if (mono_error_set_pending_exception (&error))
3093 mono_array_setref (res, i, rt);
3100 count = mono_method_signature (method->method)->generic_param_count;
3101 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3102 if (mono_error_set_pending_exception (&error))
3105 for (i = 0; i < count; i++) {
3106 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3107 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3108 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3110 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3111 if (mono_error_set_pending_exception (&error))
3114 mono_array_setref (res, i, rt);
3120 ICALL_EXPORT MonoObject *
3121 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3125 * Invoke from reflection is supposed to always be a virtual call (the API
3126 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3127 * greater flexibility.
3129 MonoMethod *m = method->method;
3130 MonoMethodSignature *sig = mono_method_signature (m);
3133 void *obj = this_arg;
3137 if (mono_security_core_clr_enabled () &&
3138 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3139 mono_error_set_pending_exception (&error);
3143 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3144 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3145 mono_error_cleanup (&error); /* FIXME does this make sense? */
3146 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3151 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3152 if (!is_ok (&error)) {
3153 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3156 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3157 char *target_name = mono_type_get_full_name (m->klass);
3158 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3159 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3161 g_free (target_name);
3165 m = mono_object_get_virtual_method (this_arg, m);
3166 /* must pass the pointer to the value for valuetype methods */
3167 if (m->klass->valuetype)
3168 obj = mono_object_unbox (this_arg);
3169 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3170 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3175 if (sig->ret->byref) {
3176 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"));
3180 pcount = params? mono_array_length (params): 0;
3181 if (pcount != sig->param_count) {
3182 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3186 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3187 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."));
3191 image = m->klass->image;
3192 if (image->assembly->ref_only) {
3193 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."));
3197 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3198 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3202 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3206 intptr_t *lower_bounds;
3207 pcount = mono_array_length (params);
3208 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3209 /* Note: the synthetized array .ctors have int32 as argument type */
3210 for (i = 0; i < pcount; ++i)
3211 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3213 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3214 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3215 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3216 if (!mono_error_ok (&error)) {
3217 mono_error_set_pending_exception (&error);
3221 for (i = 0; i < mono_array_length (arr); ++i) {
3222 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3223 if (!mono_error_ok (&error)) {
3224 mono_error_set_pending_exception (&error);
3227 mono_array_setref_fast (arr, i, subarray);
3229 return (MonoObject*)arr;
3232 if (m->klass->rank == pcount) {
3233 /* Only lengths provided. */
3234 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3235 if (!mono_error_ok (&error)) {
3236 mono_error_set_pending_exception (&error);
3240 return (MonoObject*)arr;
3242 g_assert (pcount == (m->klass->rank * 2));
3243 /* The arguments are lower-bound-length pairs */
3244 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3246 for (i = 0; i < pcount / 2; ++i) {
3247 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3248 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3251 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3252 if (!mono_error_ok (&error)) {
3253 mono_error_set_pending_exception (&error);
3257 return (MonoObject*)arr;
3260 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3261 mono_error_set_pending_exception (&error);
3265 #ifndef DISABLE_REMOTING
3266 ICALL_EXPORT MonoObject *
3267 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3270 MonoDomain *domain = mono_object_domain (method);
3271 MonoMethod *m = method->method;
3272 MonoMethodSignature *sig = mono_method_signature (m);
3273 MonoArray *out_args;
3275 int i, j, outarg_count = 0;
3277 if (m->klass == mono_defaults.object_class) {
3278 if (!strcmp (m->name, "FieldGetter")) {
3279 MonoClass *k = this_arg->vtable->klass;
3283 /* If this is a proxy, then it must be a CBO */
3284 if (k == mono_defaults.transparent_proxy_class) {
3285 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3286 this_arg = tp->rp->unwrapped_server;
3287 g_assert (this_arg);
3288 k = this_arg->vtable->klass;
3291 name = mono_array_get (params, MonoString *, 1);
3292 str = mono_string_to_utf8_checked (name, &error);
3293 if (mono_error_set_pending_exception (&error))
3297 MonoClassField* field = mono_class_get_field_from_name (k, str);
3300 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3301 if (field_klass->valuetype) {
3302 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3303 if (mono_error_set_pending_exception (&error))
3306 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3308 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3309 if (mono_error_set_pending_exception (&error))
3311 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3312 mono_array_setref (out_args, 0, result);
3319 g_assert_not_reached ();
3321 } else if (!strcmp (m->name, "FieldSetter")) {
3322 MonoClass *k = this_arg->vtable->klass;
3328 /* If this is a proxy, then it must be a CBO */
3329 if (k == mono_defaults.transparent_proxy_class) {
3330 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3331 this_arg = tp->rp->unwrapped_server;
3332 g_assert (this_arg);
3333 k = this_arg->vtable->klass;
3336 name = mono_array_get (params, MonoString *, 1);
3337 str = mono_string_to_utf8_checked (name, &error);
3338 if (mono_error_set_pending_exception (&error))
3342 MonoClassField* field = mono_class_get_field_from_name (k, str);
3345 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3346 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3348 if (field_klass->valuetype) {
3349 size = mono_type_size (field->type, &align);
3350 g_assert (size == mono_class_value_size (field_klass, NULL));
3351 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3353 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3356 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3357 if (mono_error_set_pending_exception (&error))
3359 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3368 g_assert_not_reached ();
3373 for (i = 0; i < mono_array_length (params); i++) {
3374 if (sig->params [i]->byref)
3378 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3379 if (mono_error_set_pending_exception (&error))
3382 /* handle constructors only for objects already allocated */
3383 if (!strcmp (method->method->name, ".ctor"))
3384 g_assert (this_arg);
3386 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3387 g_assert (!method->method->klass->valuetype);
3388 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3389 if (mono_error_set_pending_exception (&error))
3392 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3393 if (sig->params [i]->byref) {
3395 arg = mono_array_get (params, gpointer, i);
3396 mono_array_setref (out_args, j, arg);
3401 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3408 read_enum_value (const char *mem, int type)
3411 case MONO_TYPE_BOOLEAN:
3413 return *(guint8*)mem;
3415 return *(gint8*)mem;
3416 case MONO_TYPE_CHAR:
3418 return read16 (mem);
3420 return (gint16) read16 (mem);
3422 return read32 (mem);
3424 return (gint32) read32 (mem);
3427 return read64 (mem);
3429 g_assert_not_reached ();
3435 write_enum_value (char *mem, int type, guint64 value)
3439 case MONO_TYPE_I1: {
3440 guint8 *p = (guint8*)mem;
3446 case MONO_TYPE_CHAR: {
3447 guint16 *p = (guint16 *)mem;
3452 case MONO_TYPE_I4: {
3453 guint32 *p = (guint32 *)mem;
3458 case MONO_TYPE_I8: {
3459 guint64 *p = (guint64 *)mem;
3464 g_assert_not_reached ();
3469 ICALL_EXPORT MonoObject *
3470 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3478 domain = mono_object_domain (enumType);
3479 enumc = mono_class_from_mono_type (enumType->type);
3481 mono_class_init_checked (enumc, &error);
3482 if (mono_error_set_pending_exception (&error))
3485 etype = mono_class_enum_basetype (enumc);
3487 res = mono_object_new_checked (domain, enumc, &error);
3488 if (mono_error_set_pending_exception (&error))
3490 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3495 ICALL_EXPORT MonoBoolean
3496 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3498 int size = mono_class_value_size (a->vtable->klass, NULL);
3499 guint64 a_val = 0, b_val = 0;
3501 memcpy (&a_val, mono_object_unbox (a), size);
3502 memcpy (&b_val, mono_object_unbox (b), size);
3504 return (a_val & b_val) == b_val;
3507 ICALL_EXPORT MonoObject *
3508 ves_icall_System_Enum_get_value (MonoObject *eobj)
3520 g_assert (eobj->vtable->klass->enumtype);
3522 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3523 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3524 if (mono_error_set_pending_exception (&error))
3526 dst = (char *)res + sizeof (MonoObject);
3527 src = (char *)eobj + sizeof (MonoObject);
3528 size = mono_class_value_size (enumc, NULL);
3530 memcpy (dst, src, size);
3535 ICALL_EXPORT MonoReflectionType *
3536 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3539 MonoReflectionType *ret;
3543 klass = mono_class_from_mono_type (type->type);
3544 mono_class_init_checked (klass, &error);
3545 if (mono_error_set_pending_exception (&error))
3548 etype = mono_class_enum_basetype (klass);
3550 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3554 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3555 mono_error_set_pending_exception (&error);
3561 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3563 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3564 gpointer odata = (char *)other + sizeof (MonoObject);
3565 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3566 g_assert (basetype);
3571 if (eobj->vtable->klass != other->vtable->klass)
3574 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3575 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3576 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3579 return me > other ? 1 : -1; \
3582 switch (basetype->type) {
3584 COMPARE_ENUM_VALUES (guint8);
3586 COMPARE_ENUM_VALUES (gint8);
3587 case MONO_TYPE_CHAR:
3589 COMPARE_ENUM_VALUES (guint16);
3591 COMPARE_ENUM_VALUES (gint16);
3593 COMPARE_ENUM_VALUES (guint32);
3595 COMPARE_ENUM_VALUES (gint32);
3597 COMPARE_ENUM_VALUES (guint64);
3599 COMPARE_ENUM_VALUES (gint64);
3603 #undef COMPARE_ENUM_VALUES
3604 /* indicates that the enum was of an unsupported unerlying type */
3609 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3611 gpointer data = (char *)eobj + sizeof (MonoObject);
3612 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3613 g_assert (basetype);
3615 switch (basetype->type) {
3616 case MONO_TYPE_I1: {
3617 gint8 value = *((gint8*)data);
3618 return ((int)value ^ (int)value << 8);
3621 return *((guint8*)data);
3622 case MONO_TYPE_CHAR:
3624 return *((guint16*)data);
3626 case MONO_TYPE_I2: {
3627 gint16 value = *((gint16*)data);
3628 return ((int)(guint16)value | (((int)value) << 16));
3631 return *((guint32*)data);
3633 return *((gint32*)data);
3635 case MONO_TYPE_I8: {
3636 gint64 value = *((gint64*)data);
3637 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3640 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3646 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3648 mono_error_init (error);
3649 HANDLE_FUNCTION_ENTER();
3650 guint64 field_value;
3652 MonoTypeEnum def_type;
3654 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3656 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3658 if (mono_field_is_deleted (field))
3660 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3663 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3665 p = mono_class_get_field_default_value (field, &def_type);
3666 /* len = */ mono_metadata_decode_blob_size (p, &p);
3668 field_value = read_enum_value (p, base_type);
3669 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3671 if (*previous_value > field_value)
3674 *previous_value = field_value;
3677 HANDLE_FUNCTION_RETURN();
3680 ICALL_EXPORT MonoBoolean
3681 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3683 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3684 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3685 guint j = 0, nvalues;
3687 MonoClassField *field;
3689 guint64 previous_value = 0;
3690 gboolean sorted = TRUE;
3692 mono_error_init (error);
3693 mono_class_init_checked (enumc, error);
3694 return_val_if_nok (error, FALSE);
3696 if (!enumc->enumtype) {
3697 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3701 base_type = mono_class_enum_basetype (enumc)->type;
3703 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3704 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3705 return_val_if_nok (error, FALSE);
3706 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3707 return_val_if_nok (error, FALSE);
3710 while ((field = mono_class_get_fields (enumc, &iter))) {
3711 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3715 return_val_if_nok (error, FALSE);
3721 BFLAGS_IgnoreCase = 1,
3722 BFLAGS_DeclaredOnly = 2,
3723 BFLAGS_Instance = 4,
3725 BFLAGS_Public = 0x10,
3726 BFLAGS_NonPublic = 0x20,
3727 BFLAGS_FlattenHierarchy = 0x40,
3728 BFLAGS_InvokeMethod = 0x100,
3729 BFLAGS_CreateInstance = 0x200,
3730 BFLAGS_GetField = 0x400,
3731 BFLAGS_SetField = 0x800,
3732 BFLAGS_GetProperty = 0x1000,
3733 BFLAGS_SetProperty = 0x2000,
3734 BFLAGS_ExactBinding = 0x10000,
3735 BFLAGS_SuppressChangeType = 0x20000,
3736 BFLAGS_OptionalParamBinding = 0x40000
3739 ICALL_EXPORT GPtrArray*
3740 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3743 MonoClass *startklass, *klass;
3746 int (*compare_func) (const char *s1, const char *s2) = NULL;
3747 MonoClassField *field;
3749 if (type->type->byref) {
3750 return g_ptr_array_new ();
3753 mono_error_init (&error);
3755 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3757 klass = startklass = mono_class_from_mono_type (type->type);
3759 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3762 if (mono_class_has_failure (klass)) {
3763 mono_error_set_for_class_failure (&error, klass);
3768 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3769 guint32 flags = mono_field_get_flags (field);
3771 if (mono_field_is_deleted_with_flags (field, flags))
3773 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3774 if (bflags & BFLAGS_Public)
3776 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3777 if (bflags & BFLAGS_NonPublic) {
3784 if (flags & FIELD_ATTRIBUTE_STATIC) {
3785 if (bflags & BFLAGS_Static)
3786 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3789 if (bflags & BFLAGS_Instance)
3796 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3799 g_ptr_array_add (ptr_array, field);
3801 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3807 g_ptr_array_free (ptr_array, TRUE);
3808 mono_error_set_pending_exception (&error);
3813 method_nonpublic (MonoMethod* method, gboolean start_klass)
3815 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3816 case METHOD_ATTRIBUTE_ASSEM:
3817 return (start_klass || mono_defaults.generic_ilist_class);
3818 case METHOD_ATTRIBUTE_PRIVATE:
3820 case METHOD_ATTRIBUTE_PUBLIC:
3828 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3831 MonoClass *startklass;
3835 /*FIXME, use MonoBitSet*/
3836 guint32 method_slots_default [8];
3837 guint32 *method_slots = NULL;
3838 int (*compare_func) (const char *s1, const char *s2) = NULL;
3840 array = g_ptr_array_new ();
3842 mono_error_init (error);
3845 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3847 /* An optimization for calls made from Delegate:CreateDelegate () */
3848 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3849 method = mono_get_delegate_invoke (klass);
3852 g_ptr_array_add (array, method);
3856 mono_class_setup_methods (klass);
3857 mono_class_setup_vtable (klass);
3858 if (mono_class_has_failure (klass))
3861 if (is_generic_parameter (&klass->byval_arg))
3862 nslots = mono_class_get_vtable_size (klass->parent);
3864 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3865 if (nslots >= sizeof (method_slots_default) * 8) {
3866 method_slots = g_new0 (guint32, nslots / 32 + 1);
3868 method_slots = method_slots_default;
3869 memset (method_slots, 0, sizeof (method_slots_default));
3872 mono_class_setup_methods (klass);
3873 mono_class_setup_vtable (klass);
3874 if (mono_class_has_failure (klass))
3878 while ((method = mono_class_get_methods (klass, &iter))) {
3880 if (method->slot != -1) {
3881 g_assert (method->slot < nslots);
3882 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3884 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3885 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3888 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3890 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3891 if (bflags & BFLAGS_Public)
3893 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3899 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3900 if (bflags & BFLAGS_Static)
3901 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3904 if (bflags & BFLAGS_Instance)
3912 if (compare_func (name, method->name))
3917 g_ptr_array_add (array, method);
3919 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3921 if (method_slots != method_slots_default)
3922 g_free (method_slots);
3927 if (method_slots != method_slots_default)
3928 g_free (method_slots);
3929 g_ptr_array_free (array, TRUE);
3931 g_assert (mono_class_has_failure (klass));
3932 mono_error_set_for_class_failure (error, klass);
3936 ICALL_EXPORT GPtrArray*
3937 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3940 GPtrArray *method_array;
3943 klass = mono_class_from_mono_type (type->type);
3944 if (type->type->byref) {
3945 return g_ptr_array_new ();
3948 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3949 mono_error_set_pending_exception (&error);
3950 return method_array;
3953 ICALL_EXPORT GPtrArray*
3954 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3956 MonoClass *startklass, *klass;
3959 gpointer iter = NULL;
3960 GPtrArray *res_array;
3963 if (type->type->byref) {
3964 return g_ptr_array_new ();
3967 klass = startklass = mono_class_from_mono_type (type->type);
3969 mono_class_setup_methods (klass);
3970 if (mono_class_has_failure (klass)) {
3971 mono_error_init (&error);
3972 mono_error_set_for_class_failure (&error, klass);
3973 mono_error_set_pending_exception (&error);
3977 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3980 while ((method = mono_class_get_methods (klass, &iter))) {
3982 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3984 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3985 if (bflags & BFLAGS_Public)
3988 if (bflags & BFLAGS_NonPublic)
3994 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3995 if (bflags & BFLAGS_Static)
3996 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3999 if (bflags & BFLAGS_Instance)
4005 g_ptr_array_add (res_array, method);
4012 property_hash (gconstpointer data)
4014 MonoProperty *prop = (MonoProperty*)data;
4016 return g_str_hash (prop->name);
4020 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4022 if (method1->slot != -1 && method1->slot == method2->slot)
4025 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4026 if (method1->is_inflated)
4027 method1 = ((MonoMethodInflated*) method1)->declaring;
4028 if (method2->is_inflated)
4029 method2 = ((MonoMethodInflated*) method2)->declaring;
4032 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4036 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4038 // Properties are hide-by-name-and-signature
4039 if (!g_str_equal (prop1->name, prop2->name))
4042 /* If we see a property in a generic method, we want to
4043 compare the generic signatures, not the inflated signatures
4044 because we might conflate two properties that were
4048 public T this[T t] { getter { return t; } } // method 1
4049 public U this[U u] { getter { return u; } } // method 2
4052 If we see int Foo<int,int>::Item[int] we need to know if
4053 the indexer came from method 1 or from method 2, and we
4054 shouldn't conflate them. (Bugzilla 36283)
4056 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4059 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4066 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4071 return method_nonpublic (accessor, start_klass);
4074 ICALL_EXPORT GPtrArray*
4075 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4078 MonoClass *startklass, *klass;
4083 int (*compare_func) (const char *s1, const char *s2) = NULL;
4085 GHashTable *properties = NULL;
4086 GPtrArray *res_array;
4088 if (type->type->byref) {
4089 return g_ptr_array_new ();
4092 mono_error_init (&error);
4094 klass = startklass = mono_class_from_mono_type (type->type);
4096 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4098 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4100 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4102 mono_class_setup_methods (klass);
4103 mono_class_setup_vtable (klass);
4104 if (mono_class_has_failure (klass)) {
4105 mono_error_set_for_class_failure (&error, klass);
4110 while ((prop = mono_class_get_properties (klass, &iter))) {
4116 flags = method->flags;
4119 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4120 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4121 if (bflags & BFLAGS_Public)
4123 } else if (bflags & BFLAGS_NonPublic) {
4124 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4125 property_accessor_nonpublic(prop->set, startklass == klass)) {
4132 if (flags & METHOD_ATTRIBUTE_STATIC) {
4133 if (bflags & BFLAGS_Static)
4134 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4137 if (bflags & BFLAGS_Instance)
4145 if (propname != NULL && compare_func (propname, prop->name))
4148 if (g_hash_table_lookup (properties, prop))
4151 g_ptr_array_add (res_array, prop);
4153 g_hash_table_insert (properties, prop, prop);
4155 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4158 g_hash_table_destroy (properties);
4165 g_hash_table_destroy (properties);
4166 g_ptr_array_free (res_array, TRUE);
4168 mono_error_set_pending_exception (&error);
4174 event_hash (gconstpointer data)
4176 MonoEvent *event = (MonoEvent*)data;
4178 return g_str_hash (event->name);
4182 event_equal (MonoEvent *event1, MonoEvent *event2)
4184 // Events are hide-by-name
4185 return g_str_equal (event1->name, event2->name);
4188 ICALL_EXPORT GPtrArray*
4189 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4192 MonoClass *startklass, *klass;
4197 int (*compare_func) (const char *s1, const char *s2) = NULL;
4198 GHashTable *events = NULL;
4199 GPtrArray *res_array;
4201 if (type->type->byref) {
4202 return g_ptr_array_new ();
4205 mono_error_init (&error);
4207 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4209 res_array = g_ptr_array_sized_new (4);
4211 klass = startklass = mono_class_from_mono_type (type->type);
4213 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4215 mono_class_setup_methods (klass);
4216 mono_class_setup_vtable (klass);
4217 if (mono_class_has_failure (klass)) {
4218 mono_error_set_for_class_failure (&error, klass);
4223 while ((event = mono_class_get_events (klass, &iter))) {
4225 method = event->add;
4227 method = event->remove;
4229 method = event->raise;
4231 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4232 if (bflags & BFLAGS_Public)
4234 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4235 if (bflags & BFLAGS_NonPublic)
4240 if (bflags & BFLAGS_NonPublic)
4246 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4247 if (bflags & BFLAGS_Static)
4248 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4251 if (bflags & BFLAGS_Instance)
4256 if (bflags & BFLAGS_Instance)
4261 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4264 if (g_hash_table_lookup (events, event))
4267 g_ptr_array_add (res_array, event);
4269 g_hash_table_insert (events, event, event);
4271 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4274 g_hash_table_destroy (events);
4280 g_hash_table_destroy (events);
4282 g_ptr_array_free (res_array, TRUE);
4284 mono_error_set_pending_exception (&error);
4288 ICALL_EXPORT GPtrArray *
4289 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4295 GPtrArray *res_array;
4297 if (type->type->byref) {
4298 return g_ptr_array_new ();
4301 klass = mono_class_from_mono_type (type->type);
4304 * If a nested type is generic, return its generic type definition.
4305 * Note that this means that the return value is essentially the set
4306 * of nested types of the generic type definition of @klass.
4308 * A note in MSDN claims that a generic type definition can have
4309 * nested types that aren't generic. In any case, the container of that
4310 * nested type would be the generic type definition.
4312 if (mono_class_is_ginst (klass))
4313 klass = mono_class_get_generic_class (klass)->container_class;
4315 res_array = g_ptr_array_new ();
4318 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4320 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4321 if (bflags & BFLAGS_Public)
4324 if (bflags & BFLAGS_NonPublic)
4330 if (str != NULL && strcmp (nested->name, str))
4333 g_ptr_array_add (res_array, &nested->byval_arg);
4339 ICALL_EXPORT MonoReflectionType*
4340 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4343 MonoReflectionType *ret;
4345 MonoType *type = NULL;
4346 MonoTypeNameParse info;
4347 gboolean type_resolve;
4349 /* On MS.NET, this does not fire a TypeResolve event */
4350 type_resolve = TRUE;
4351 str = mono_string_to_utf8_checked (name, &error);
4352 if (mono_error_set_pending_exception (&error))
4354 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4355 if (!mono_reflection_parse_type (str, &info)) {
4357 mono_reflection_free_type_info (&info);
4359 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4362 /*g_print ("failed parse\n");*/
4366 if (info.assembly.name) {
4368 mono_reflection_free_type_info (&info);
4370 /* 1.0 and 2.0 throw different exceptions */
4371 if (mono_defaults.generic_ilist_class)
4372 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4374 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4380 if (module != NULL) {
4381 if (module->image) {
4382 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4383 if (!is_ok (&error)) {
4385 mono_reflection_free_type_info (&info);
4386 mono_error_set_pending_exception (&error);
4393 if (assembly_is_dynamic (assembly->assembly)) {
4394 /* Enumerate all modules */
4395 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4399 if (abuilder->modules) {
4400 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4401 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4402 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4403 if (!is_ok (&error)) {
4405 mono_reflection_free_type_info (&info);
4406 mono_error_set_pending_exception (&error);
4414 if (!type && abuilder->loaded_modules) {
4415 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4416 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4417 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4418 if (!is_ok (&error)) {
4420 mono_reflection_free_type_info (&info);
4421 mono_error_set_pending_exception (&error);
4430 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4431 if (!is_ok (&error)) {
4433 mono_reflection_free_type_info (&info);
4434 mono_error_set_pending_exception (&error);
4439 mono_reflection_free_type_info (&info);
4441 MonoException *e = NULL;
4444 e = mono_get_exception_type_load (name, NULL);
4447 mono_set_pending_exception (e);
4451 if (type->type == MONO_TYPE_CLASS) {
4452 MonoClass *klass = mono_type_get_class (type);
4454 /* need to report exceptions ? */
4455 if (throwOnError && mono_class_has_failure (klass)) {
4456 /* report SecurityException (or others) that occured when loading the assembly */
4457 mono_error_set_for_class_failure (&error, klass);
4458 mono_error_set_pending_exception (&error);
4463 /* g_print ("got it\n"); */
4464 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4465 mono_error_set_pending_exception (&error);
4471 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4474 gchar *shadow_ini_file;
4477 /* Check for shadow-copied assembly */
4478 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4479 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4481 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4482 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4488 g_free (shadow_ini_file);
4489 if (content != NULL) {
4492 *filename = content;
4499 ICALL_EXPORT MonoString *
4500 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4502 MonoDomain *domain = mono_object_domain (assembly);
4503 MonoAssembly *mass = assembly->assembly;
4504 MonoString *res = NULL;
4509 if (g_path_is_absolute (mass->image->name)) {
4510 absolute = g_strdup (mass->image->name);
4511 dirname = g_path_get_dirname (absolute);
4513 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4514 dirname = g_strdup (mass->basedir);
4517 replace_shadow_path (domain, dirname, &absolute);
4520 mono_icall_make_platform_path (absolute);
4523 uri = g_filename_to_uri (absolute, NULL, NULL);
4525 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4526 uri = g_strconcat (prepend, absolute, NULL);
4530 res = mono_string_new (domain, uri);
4537 ICALL_EXPORT MonoBoolean
4538 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4540 MonoAssembly *mass = assembly->assembly;
4542 return mass->in_gac;
4545 ICALL_EXPORT MonoReflectionAssembly*
4546 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4551 MonoImageOpenStatus status;
4552 MonoReflectionAssembly* result = NULL;
4554 name = mono_string_to_utf8_checked (mname, &error);
4555 if (mono_error_set_pending_exception (&error))
4557 res = mono_assembly_load_with_partial_name (name, &status);
4563 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4565 mono_error_set_pending_exception (&error);
4569 ICALL_EXPORT MonoStringHandle
4570 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4572 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4573 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4574 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4577 ICALL_EXPORT MonoBoolean
4578 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4580 return assembly->assembly->ref_only;
4583 ICALL_EXPORT MonoStringHandle
4584 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4586 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4587 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4589 return mono_string_new_handle (domain, assembly->image->version, error);
4592 ICALL_EXPORT MonoReflectionMethod*
4593 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4596 MonoReflectionMethod *res = NULL;
4599 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4603 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4604 if (!mono_error_ok (&error))
4607 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4610 if (!mono_error_ok (&error))
4611 mono_error_set_pending_exception (&error);
4615 ICALL_EXPORT MonoReflectionModule*
4616 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4619 MonoReflectionModule *result = NULL;
4620 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4621 if (!mono_error_ok (&error))
4622 mono_error_set_pending_exception (&error);
4626 ICALL_EXPORT MonoArray*
4627 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4630 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4631 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4632 if (mono_error_set_pending_exception (&error))
4637 for (i = 0; i < table->rows; ++i) {
4638 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4639 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4644 ICALL_EXPORT MonoStringHandle
4645 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4648 guint8 aotid_sum = 0;
4649 MonoDomain* domain = mono_domain_get ();
4651 if (!domain->entry_assembly || !domain->entry_assembly->image)
4654 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4656 for (i = 0; i < 16; ++i)
4657 aotid_sum |= (*aotid)[i];
4662 gchar *guid = mono_guid_to_string((guint8*) aotid);
4663 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4669 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision, MonoError *error)
4671 static MonoMethod *create_version = NULL;
4675 mono_error_init (error);
4678 if (!create_version) {
4679 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4680 create_version = mono_method_desc_search_in_class (desc, mono_class_get_system_version_class ());
4681 g_assert (create_version);
4682 mono_method_desc_free (desc);
4688 args [3] = &revision;
4689 result = mono_object_new_checked (domain, mono_class_get_system_version_class (), error);
4690 return_val_if_nok (error, NULL);
4692 mono_runtime_invoke_checked (create_version, result, args, error);
4693 return_val_if_nok (error, NULL);
4698 ICALL_EXPORT MonoArray*
4699 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4703 MonoDomain *domain = mono_object_domain (assembly);
4705 static MonoMethod *create_culture = NULL;
4706 MonoImage *image = assembly->assembly->image;
4710 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4713 result = mono_array_new_checked (domain, mono_class_get_assembly_name_class (), count, &error);
4714 if (mono_error_set_pending_exception (&error))
4718 if (count > 0 && !create_culture) {
4719 MonoMethodDesc *desc = mono_method_desc_new (
4720 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4721 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4722 g_assert (create_culture);
4723 mono_method_desc_free (desc);
4726 for (i = 0; i < count; i++) {
4727 MonoObject *version;
4728 MonoReflectionAssemblyName *aname;
4729 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4731 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4733 aname = (MonoReflectionAssemblyName *) mono_object_new_checked (
4734 domain, mono_class_get_assembly_name_class (), &error);
4735 if (mono_error_set_pending_exception (&error))
4738 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4740 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4741 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4742 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4743 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4744 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4745 aname->versioncompat = 1; /* SameMachine (default) */
4746 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4748 version = create_version (domain, aname->major, aname->minor, aname->build, aname->revision, &error);
4749 if (mono_error_set_pending_exception (&error))
4752 MONO_OBJECT_SETREF (aname, version, version);
4754 if (create_culture) {
4756 MonoBoolean assembly_ref = 1;
4757 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4758 args [1] = &assembly_ref;
4760 o = mono_runtime_invoke_checked (create_culture, NULL, args, &error);
4761 if (mono_error_set_pending_exception (&error))
4764 MONO_OBJECT_SETREF (aname, cultureInfo, o);
4767 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4768 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4769 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4771 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4772 /* public key token isn't copied - the class library will
4773 automatically generate it from the public key if required */
4774 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4775 if (mono_error_set_pending_exception (&error))
4778 MONO_OBJECT_SETREF (aname, publicKey, pkey);
4779 memcpy (mono_array_addr (pkey, guint8, 0), pkey_ptr, pkey_len);
4781 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4782 if (mono_error_set_pending_exception (&error))
4785 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4786 memcpy (mono_array_addr (keyToken, guint8, 0), pkey_ptr, pkey_len);
4789 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, &error);
4790 if (mono_error_set_pending_exception (&error))
4793 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4796 /* note: this function doesn't return the codebase on purpose (i.e. it can
4797 be used under partial trust as path information isn't present). */
4799 mono_array_setref (result, i, aname);
4804 /* move this in some file in mono/util/ */
4806 g_concat_dir_and_file (const char *dir, const char *file)
4808 g_return_val_if_fail (dir != NULL, NULL);
4809 g_return_val_if_fail (file != NULL, NULL);
4812 * If the directory name doesn't have a / on the end, we need
4813 * to add one so we get a proper path to the file
4815 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4816 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4818 return g_strconcat (dir, file, NULL);
4822 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4825 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4827 guint32 cols [MONO_MANIFEST_SIZE];
4828 guint32 impl, file_idx;
4832 char *n = mono_string_to_utf8_checked (name, &error);
4833 if (mono_error_set_pending_exception (&error))
4836 for (i = 0; i < table->rows; ++i) {
4837 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4838 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4839 if (strcmp (val, n) == 0)
4843 if (i == table->rows)
4846 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4849 * this code should only be called after obtaining the
4850 * ResourceInfo and handling the other cases.
4852 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4853 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4855 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4856 if (mono_error_set_pending_exception (&error) || !module)
4860 module = assembly->assembly->image;
4863 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4864 if (mono_error_set_pending_exception (&error))
4866 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4868 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4871 ICALL_EXPORT gboolean
4872 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4875 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4877 guint32 cols [MONO_MANIFEST_SIZE];
4878 guint32 file_cols [MONO_FILE_SIZE];
4882 n = mono_string_to_utf8_checked (name, &error);
4883 if (mono_error_set_pending_exception (&error))
4885 for (i = 0; i < table->rows; ++i) {
4886 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4887 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4888 if (strcmp (val, n) == 0)
4892 if (i == table->rows)
4895 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4896 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4899 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4900 case MONO_IMPLEMENTATION_FILE:
4901 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4902 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4903 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4904 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4905 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4906 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4909 info->location = RESOURCE_LOCATION_EMBEDDED;
4912 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4913 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4914 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4915 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4916 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4917 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4919 mono_set_pending_exception (ex);
4922 MonoReflectionAssembly *assm_obj;
4923 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4925 mono_error_set_pending_exception (&error);
4928 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4930 /* Obtain info recursively */
4931 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4932 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4935 case MONO_IMPLEMENTATION_EXP_TYPE:
4936 g_assert_not_reached ();
4944 ICALL_EXPORT MonoObject*
4945 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4948 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4949 MonoArray *result = NULL;
4954 /* check hash if needed */
4956 n = mono_string_to_utf8_checked (name, &error);
4957 if (mono_error_set_pending_exception (&error))
4960 for (i = 0; i < table->rows; ++i) {
4961 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4962 if (strcmp (val, n) == 0) {
4965 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4966 fn = mono_string_new (mono_object_domain (assembly), n);
4968 return (MonoObject*)fn;
4976 for (i = 0; i < table->rows; ++i) {
4977 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4981 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4982 if (mono_error_set_pending_exception (&error))
4987 for (i = 0; i < table->rows; ++i) {
4988 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4989 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4990 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4991 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4996 return (MonoObject*)result;
4999 ICALL_EXPORT MonoArray*
5000 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
5003 MonoDomain *domain = mono_domain_get();
5006 int i, j, file_count = 0;
5007 MonoImage **modules;
5008 guint32 module_count, real_module_count;
5009 MonoTableInfo *table;
5010 guint32 cols [MONO_FILE_SIZE];
5011 MonoImage *image = assembly->assembly->image;
5013 g_assert (image != NULL);
5014 g_assert (!assembly_is_dynamic (assembly->assembly));
5016 table = &image->tables [MONO_TABLE_FILE];
5017 file_count = table->rows;
5019 modules = image->modules;
5020 module_count = image->module_count;
5022 real_module_count = 0;
5023 for (i = 0; i < module_count; ++i)
5025 real_module_count ++;
5027 klass = mono_class_get_module_class ();
5028 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
5029 if (mono_error_set_pending_exception (&error))
5032 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
5033 if (mono_error_set_pending_exception (&error))
5036 mono_array_setref (res, 0, image_obj);
5038 for (i = 0; i < module_count; ++i)
5040 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
5041 if (mono_error_set_pending_exception (&error))
5043 mono_array_setref (res, j, rm);
5047 for (i = 0; i < file_count; ++i, ++j) {
5048 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
5049 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
5050 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
5051 if (mono_error_set_pending_exception (&error))
5053 mono_array_setref (res, j, rm);
5056 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
5057 if (mono_error_set_pending_exception (&error))
5060 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
5061 mono_set_pending_exception (mono_get_exception_file_not_found2 (NULL, fname));
5064 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
5065 if (mono_error_set_pending_exception (&error))
5067 mono_array_setref (res, j, rm);
5074 ICALL_EXPORT MonoReflectionMethod*
5075 ves_icall_GetCurrentMethod (void)
5077 MonoReflectionMethod *res = NULL;
5080 MonoMethod *m = mono_method_get_last_managed ();
5083 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5087 while (m->is_inflated)
5088 m = ((MonoMethodInflated*)m)->declaring;
5090 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5091 mono_error_set_pending_exception (&error);
5097 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5100 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5103 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5104 //method is inflated, we should inflate it on the other class
5105 MonoGenericContext ctx;
5106 ctx.method_inst = inflated->context.method_inst;
5107 ctx.class_inst = inflated->context.class_inst;
5108 if (mono_class_is_ginst (klass))
5109 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5110 else if (mono_class_is_gtd (klass))
5111 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5112 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5113 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5117 mono_class_setup_methods (method->klass);
5118 if (mono_class_has_failure (method->klass))
5120 int mcount = mono_class_get_method_count (method->klass);
5121 for (i = 0; i < mcount; ++i) {
5122 if (method->klass->methods [i] == method) {
5127 mono_class_setup_methods (klass);
5128 if (mono_class_has_failure (klass))
5130 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5131 return klass->methods [offset];
5134 ICALL_EXPORT MonoReflectionMethod*
5135 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5137 MonoReflectionMethod *res = NULL;
5140 if (type && generic_check) {
5141 klass = mono_class_from_mono_type (type);
5142 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5145 if (method->klass != klass) {
5146 method = mono_method_get_equivalent_method (method, klass);
5151 klass = mono_class_from_mono_type (type);
5153 klass = method->klass;
5154 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5155 mono_error_set_pending_exception (&error);
5159 ICALL_EXPORT MonoReflectionMethodBody*
5160 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5163 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5164 mono_error_set_pending_exception (&error);
5168 ICALL_EXPORT MonoReflectionAssembly*
5169 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5172 MonoReflectionAssembly *result;
5173 MonoMethod *dest = NULL;
5175 mono_stack_walk_no_il (get_executing, &dest);
5177 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5179 mono_error_set_pending_exception (&error);
5184 ICALL_EXPORT MonoReflectionAssembly*
5185 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5188 MonoReflectionAssembly *result;
5189 MonoDomain* domain = mono_domain_get ();
5191 if (!domain->entry_assembly)
5194 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5196 mono_error_set_pending_exception (&error);
5200 ICALL_EXPORT MonoReflectionAssembly*
5201 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5206 MonoReflectionAssembly *result;
5209 mono_stack_walk_no_il (get_executing, &dest);
5211 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5215 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5218 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5220 mono_error_set_pending_exception (&error);
5224 ICALL_EXPORT MonoStringHandle
5225 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5226 gboolean assembly_qualified, MonoError *error)
5228 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5229 MonoType *type = MONO_HANDLE_RAW (object)->type;
5230 MonoTypeNameFormat format;
5231 MonoStringHandle res;
5235 format = assembly_qualified ?
5236 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5237 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5239 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5241 name = mono_type_get_name_full (type, format);
5243 return NULL_HANDLE_STRING;
5245 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5247 return NULL_HANDLE_STRING;
5250 res = mono_string_new_handle (domain, name, error);
5257 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5260 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5262 mono_class_init_checked (klass, &error);
5263 mono_error_set_pending_exception (&error);
5264 return mono_security_core_clr_class_level (klass);
5268 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5270 MonoClassField *field = rfield->field;
5271 return mono_security_core_clr_field_level (field, TRUE);
5275 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5277 MonoMethod *method = rfield->method;
5278 return mono_security_core_clr_method_level (method, TRUE);
5282 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token, MonoError *error)
5284 static MonoMethod *create_culture = NULL;
5288 const char *pkey_ptr;
5290 MonoBoolean assembly_ref = 0;
5292 mono_error_init (error);
5294 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
5295 aname->major = name->major;
5296 aname->minor = name->minor;
5297 aname->build = name->build;
5298 aname->flags = name->flags;
5299 aname->revision = name->revision;
5300 aname->hashalg = name->hash_alg;
5301 aname->versioncompat = 1; /* SameMachine (default) */
5302 aname->processor_architecture = name->arch;
5304 if (by_default_version) {
5305 MonoObject *version;
5307 version = create_version (domain, name->major, name->minor, name->build, name->revision, error);
5308 return_if_nok (error);
5310 MONO_OBJECT_SETREF (aname, version, version);
5314 if (absolute != NULL && *absolute != '\0') {
5317 codebase = g_strdup (absolute);
5319 mono_icall_make_platform_path (codebase);
5321 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5323 result = g_strconcat (prepend, codebase, NULL);
5329 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
5333 if (!create_culture) {
5334 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
5335 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
5336 g_assert (create_culture);
5337 mono_method_desc_free (desc);
5340 if (name->culture) {
5341 args [0] = mono_string_new (domain, name->culture);
5342 args [1] = &assembly_ref;
5344 obj = mono_runtime_invoke_checked (create_culture, NULL, args, error);
5345 return_if_nok (error);
5347 MONO_OBJECT_SETREF (aname, cultureInfo, obj);
5350 if (name->public_key) {
5351 pkey_ptr = (char*)name->public_key;
5352 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
5354 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, error);
5355 return_if_nok (error);
5356 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5357 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
5358 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5359 } else if (default_publickey) {
5360 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5361 return_if_nok (error);
5362 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5363 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5366 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5367 if (name->public_key_token [0]) {
5371 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 8, error);
5372 return_if_nok (error);
5374 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5375 p = mono_array_addr (keyToken, char, 0);
5377 for (i = 0, j = 0; i < 8; i++) {
5378 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
5379 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
5382 } else if (default_token) {
5383 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5384 return_if_nok (error);
5385 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5389 ICALL_EXPORT MonoString *
5390 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5392 MonoDomain *domain = mono_object_domain (assembly);
5393 MonoAssembly *mass = assembly->assembly;
5397 name = mono_stringify_assembly_name (&mass->aname);
5398 res = mono_string_new (domain, name);
5404 ICALL_EXPORT MonoAssemblyName *
5405 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5407 return &mass->aname;
5411 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
5415 MonoImageOpenStatus status = MONO_IMAGE_OK;
5418 MonoAssemblyName name;
5421 filename = mono_string_to_utf8_checked (fname, &error);
5422 if (mono_error_set_pending_exception (&error))
5425 dirname = g_path_get_dirname (filename);
5426 replace_shadow_path (mono_domain_get (), dirname, &filename);
5429 image = mono_image_open (filename, &status);
5435 if (status == MONO_IMAGE_IMAGE_INVALID)
5436 exc = mono_get_exception_bad_image_format2 (NULL, fname);
5438 exc = mono_get_exception_file_not_found2 (NULL, fname);
5439 mono_set_pending_exception (exc);
5443 res = mono_assembly_fill_assembly_name (image, &name);
5445 mono_image_close (image);
5447 mono_set_pending_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5451 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE, FALSE, TRUE, &error);
5452 mono_error_set_pending_exception (&error);
5454 mono_image_close (image);
5458 ICALL_EXPORT MonoBoolean
5459 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5460 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5462 MonoBoolean result = FALSE;
5463 MonoDeclSecurityEntry entry;
5465 /* SecurityAction.RequestMinimum */
5466 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5467 *minimum = entry.blob;
5468 *minLength = entry.size;
5471 /* SecurityAction.RequestOptional */
5472 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5473 *optional = entry.blob;
5474 *optLength = entry.size;
5477 /* SecurityAction.RequestRefuse */
5478 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5479 *refused = entry.blob;
5480 *refLength = entry.size;
5488 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5490 guint32 attrs, visibility;
5492 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5493 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5494 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5497 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5503 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5505 mono_error_init (error);
5506 HANDLE_FUNCTION_ENTER ();
5507 MonoError klass_error;
5508 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5511 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5512 return_if_nok (error);
5514 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5516 MonoException *ex = mono_error_convert_to_exception (error);
5517 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5519 HANDLE_FUNCTION_RETURN ();
5522 static MonoArrayHandle
5523 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5525 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5528 mono_error_init (error);
5530 /* we start the count from 1 because we skip the special type <Module> */
5533 for (i = 1; i < tdef->rows; ++i) {
5534 if (mono_module_type_is_visible (tdef, image, i + 1))
5538 count = tdef->rows - 1;
5540 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5541 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5542 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5543 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5545 for (i = 1; i < tdef->rows; ++i) {
5546 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5547 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5548 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5557 mono_module_get_types_legacy (MonoDomain *domain, MonoImage *image, MonoArray **exceptions_raw, MonoBoolean exportedOnly, MonoError *error)
5559 /* FIXME: don't use this function, update callers to use mono_module_get_types */
5560 HANDLE_FUNCTION_ENTER ();
5561 mono_error_init (error);
5562 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5563 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5564 mono_gc_wbarrier_generic_store (exceptions_raw, MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, exceptions)));
5565 HANDLE_FUNCTION_RETURN_OBJ (res);
5568 ICALL_EXPORT MonoArray*
5569 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
5572 MonoArray *res = NULL;
5573 MonoArray *exceptions = NULL;
5574 MonoImage *image = NULL;
5575 MonoTableInfo *table = NULL;
5578 int i, len, ex_count;
5580 domain = mono_object_domain (assembly);
5582 g_assert (!assembly_is_dynamic (assembly->assembly));
5583 image = assembly->assembly->image;
5584 table = &image->tables [MONO_TABLE_FILE];
5585 res = mono_module_get_types_legacy (domain, image, &exceptions, exportedOnly, &error); /* FIXME no _legacy */
5586 if (mono_error_set_pending_exception (&error))
5589 /* Append data from all modules in the assembly */
5590 for (i = 0; i < table->rows; ++i) {
5591 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5592 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, &error);
5593 if (mono_error_set_pending_exception (&error))
5599 res2 = mono_module_get_types_legacy (domain, loaded_image, &ex2, exportedOnly, &error); /* FIXME no _legacy */
5600 if (mono_error_set_pending_exception (&error))
5604 /* Append the new types to the end of the array */
5605 if (mono_array_length (res2) > 0) {
5607 MonoArray *res3, *ex3;
5609 len1 = mono_array_length (res);
5610 len2 = mono_array_length (res2);
5612 res3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5613 if (mono_error_set_pending_exception (&error))
5615 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5616 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5619 ex3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5620 if (mono_error_set_pending_exception (&error))
5622 mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
5623 mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
5630 /* the ReflectionTypeLoadException must have all the types (Types property),
5631 * NULL replacing types which throws an exception. The LoaderException must
5632 * contain all exceptions for NULL items.
5635 len = mono_array_length (res);
5638 for (i = 0; i < len; i++) {
5639 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (res, gpointer, i);
5643 klass = mono_type_get_class (t->type);
5644 if ((klass != NULL) && mono_class_has_failure (klass)) {
5645 /* keep the class in the list */
5646 list = g_list_append (list, klass);
5647 /* and replace Type with NULL */
5648 mono_array_setref (res, i, NULL);
5655 if (list || ex_count) {
5657 MonoException *exc = NULL;
5658 MonoArray *exl = NULL;
5659 int j, length = g_list_length (list) + ex_count;
5661 exl = mono_array_new_checked (domain, mono_defaults.exception_class, length, &error);
5662 if (mono_error_set_pending_exception (&error)) {
5666 /* Types for which mono_class_get_checked () succeeded */
5667 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5668 MonoException *exc = mono_class_get_exception_for_failure ((MonoClass *)tmp->data);
5669 mono_array_setref (exl, i, exc);
5671 /* Types for which it don't */
5672 for (j = 0; j < mono_array_length (exceptions); ++j) {
5673 MonoException *exc = mono_array_get (exceptions, MonoException*, j);
5675 g_assert (i < length);
5676 mono_array_setref (exl, i, exc);
5683 exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
5684 if (!is_ok (&error)) {
5685 mono_error_set_pending_exception (&error);
5688 mono_set_pending_exception (exc);
5696 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname)
5698 mono_assembly_name_free (aname);
5701 ICALL_EXPORT gboolean
5702 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5704 *is_version_definited = *is_token_defined = FALSE;
5706 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5709 ICALL_EXPORT MonoReflectionTypeHandle
5710 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5712 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5713 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5718 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5720 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5721 /* These images do not have a global type */
5724 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5728 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5734 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5736 /*if (module->image)
5737 mono_image_close (module->image);*/
5740 ICALL_EXPORT MonoStringHandle
5741 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5743 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5744 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5747 return mono_string_new_handle (domain, image->guid, error);
5751 static inline gpointer
5752 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5754 return (gpointer) (-1);
5756 #endif /* HOST_WIN32 */
5758 ICALL_EXPORT gpointer
5759 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5761 return mono_icall_module_get_hinstance (module);
5765 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5767 if (image_is_dynamic (image)) {
5768 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5769 *pe_kind = dyn->pe_kind;
5770 *machine = dyn->machine;
5773 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5774 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5779 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5781 return (image->md_version_major << 16) | (image->md_version_minor);
5784 ICALL_EXPORT MonoArrayHandle
5785 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5787 mono_error_init (error);
5789 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5790 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5793 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5796 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5797 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5798 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5800 int n = mono_array_handle_length (exceptions);
5801 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5802 for (int i = 0; i < n; ++i) {
5803 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5804 if (!MONO_HANDLE_IS_NULL (ex)) {
5805 mono_error_set_exception_handle (error, ex);
5806 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5814 mono_memberref_is_method (MonoImage *image, guint32 token)
5816 if (!image_is_dynamic (image)) {
5817 guint32 cols [MONO_MEMBERREF_SIZE];
5819 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5820 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5821 mono_metadata_decode_blob_size (sig, &sig);
5822 return (*sig != 0x6);
5825 MonoClass *handle_class;
5827 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5828 mono_error_cleanup (&error); /* just probing, ignore error */
5832 return mono_defaults.methodhandle_class == handle_class;
5837 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5840 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5841 mono_array_addr (type_args, MonoType*, 0));
5843 context->class_inst = NULL;
5845 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5846 mono_array_addr (method_args, MonoType*, 0));
5848 context->method_inst = NULL;
5851 ICALL_EXPORT MonoType*
5852 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5855 int table = mono_metadata_token_table (token);
5856 int index = mono_metadata_token_index (token);
5857 MonoGenericContext context;
5860 *resolve_error = ResolveTokenError_Other;
5862 /* Validate token */
5863 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5864 (table != MONO_TABLE_TYPESPEC)) {
5865 *resolve_error = ResolveTokenError_BadTable;
5869 if (image_is_dynamic (image)) {
5870 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5871 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5872 mono_error_cleanup (&error);
5873 return klass ? &klass->byval_arg : NULL;
5876 init_generic_context_from_args (&context, type_args, method_args);
5877 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5878 mono_error_cleanup (&error);
5879 return klass ? &klass->byval_arg : NULL;
5882 if ((index <= 0) || (index > image->tables [table].rows)) {
5883 *resolve_error = ResolveTokenError_OutOfRange;
5887 init_generic_context_from_args (&context, type_args, method_args);
5888 klass = mono_class_get_checked (image, token, &error);
5890 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5891 if (!mono_error_ok (&error)) {
5892 mono_error_set_pending_exception (&error);
5897 return &klass->byval_arg;
5902 ICALL_EXPORT MonoMethod*
5903 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5906 int table = mono_metadata_token_table (token);
5907 int index = mono_metadata_token_index (token);
5908 MonoGenericContext context;
5911 *resolve_error = ResolveTokenError_Other;
5913 /* Validate token */
5914 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5915 (table != MONO_TABLE_MEMBERREF)) {
5916 *resolve_error = ResolveTokenError_BadTable;
5920 if (image_is_dynamic (image)) {
5921 if (table == MONO_TABLE_METHOD) {
5922 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5923 mono_error_cleanup (&error);
5927 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5928 *resolve_error = ResolveTokenError_BadTable;
5932 init_generic_context_from_args (&context, type_args, method_args);
5933 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5934 mono_error_cleanup (&error);
5938 if ((index <= 0) || (index > image->tables [table].rows)) {
5939 *resolve_error = ResolveTokenError_OutOfRange;
5942 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5943 *resolve_error = ResolveTokenError_BadTable;
5947 init_generic_context_from_args (&context, type_args, method_args);
5948 method = mono_get_method_checked (image, token, NULL, &context, &error);
5949 mono_error_set_pending_exception (&error);
5954 ICALL_EXPORT MonoString*
5955 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5958 int index = mono_metadata_token_index (token);
5960 *resolve_error = ResolveTokenError_Other;
5962 /* Validate token */
5963 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5964 *resolve_error = ResolveTokenError_BadTable;
5968 if (image_is_dynamic (image)) {
5969 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5970 mono_error_cleanup (&error);
5974 if ((index <= 0) || (index >= image->heap_us.size)) {
5975 *resolve_error = ResolveTokenError_OutOfRange;
5979 /* FIXME: What to do if the index points into the middle of a string ? */
5981 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5982 mono_error_set_pending_exception (&error);
5986 ICALL_EXPORT MonoClassField*
5987 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5991 int table = mono_metadata_token_table (token);
5992 int index = mono_metadata_token_index (token);
5993 MonoGenericContext context;
5994 MonoClassField *field;
5996 *resolve_error = ResolveTokenError_Other;
5998 /* Validate token */
5999 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
6000 *resolve_error = ResolveTokenError_BadTable;
6004 if (image_is_dynamic (image)) {
6005 if (table == MONO_TABLE_FIELD) {
6006 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
6007 mono_error_cleanup (&error);
6011 if (mono_memberref_is_method (image, token)) {
6012 *resolve_error = ResolveTokenError_BadTable;
6016 init_generic_context_from_args (&context, type_args, method_args);
6017 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
6018 mono_error_cleanup (&error);
6022 if ((index <= 0) || (index > image->tables [table].rows)) {
6023 *resolve_error = ResolveTokenError_OutOfRange;
6026 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
6027 *resolve_error = ResolveTokenError_BadTable;
6031 init_generic_context_from_args (&context, type_args, method_args);
6032 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
6033 mono_error_set_pending_exception (&error);
6039 ICALL_EXPORT MonoObject*
6040 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
6044 int table = mono_metadata_token_table (token);
6046 *error = ResolveTokenError_Other;
6049 case MONO_TABLE_TYPEDEF:
6050 case MONO_TABLE_TYPEREF:
6051 case MONO_TABLE_TYPESPEC: {
6052 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
6054 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
6055 mono_error_set_pending_exception (&merror);
6062 case MONO_TABLE_METHOD:
6063 case MONO_TABLE_METHODSPEC: {
6064 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6066 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6067 mono_error_set_pending_exception (&merror);
6073 case MONO_TABLE_FIELD: {
6074 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6076 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6077 mono_error_set_pending_exception (&merror);
6083 case MONO_TABLE_MEMBERREF:
6084 if (mono_memberref_is_method (image, token)) {
6085 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6087 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6088 mono_error_set_pending_exception (&merror);
6095 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6097 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6098 mono_error_set_pending_exception (&merror);
6107 *error = ResolveTokenError_BadTable;
6113 ICALL_EXPORT MonoArray*
6114 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6117 int table = mono_metadata_token_table (token);
6118 int idx = mono_metadata_token_index (token);
6119 MonoTableInfo *tables = image->tables;
6124 *resolve_error = ResolveTokenError_OutOfRange;
6126 /* FIXME: Support other tables ? */
6127 if (table != MONO_TABLE_STANDALONESIG)
6130 if (image_is_dynamic (image))
6133 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6136 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6138 ptr = mono_metadata_blob_heap (image, sig);
6139 len = mono_metadata_decode_blob_size (ptr, &ptr);
6141 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6142 if (mono_error_set_pending_exception (&error))
6144 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6148 ICALL_EXPORT MonoBoolean
6149 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6155 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6161 check_for_invalid_type (MonoClass *klass, MonoError *error)
6165 mono_error_init (error);
6167 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6170 name = mono_type_get_full_name (klass);
6171 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6173 ICALL_EXPORT MonoReflectionType *
6174 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6177 MonoReflectionType *ret;
6178 MonoClass *klass, *aklass;
6180 klass = mono_class_from_mono_type (type->type);
6181 check_for_invalid_type (klass, &error);
6182 if (mono_error_set_pending_exception (&error))
6185 if (rank == 0) //single dimentional array
6186 aklass = mono_array_class_get (klass, 1);
6188 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6190 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6191 mono_error_set_pending_exception (&error);
6196 ICALL_EXPORT MonoReflectionType *
6197 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6200 MonoReflectionType *ret;
6203 klass = mono_class_from_mono_type (type->type);
6204 mono_class_init_checked (klass, &error);
6205 if (mono_error_set_pending_exception (&error))
6208 check_for_invalid_type (klass, &error);
6209 if (mono_error_set_pending_exception (&error))
6212 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6213 mono_error_set_pending_exception (&error);
6218 ICALL_EXPORT MonoReflectionType *
6219 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6222 MonoReflectionType *ret;
6223 MonoClass *klass, *pklass;
6225 klass = mono_class_from_mono_type (type->type);
6226 mono_class_init_checked (klass, &error);
6227 if (mono_error_set_pending_exception (&error))
6229 check_for_invalid_type (klass, &error);
6230 if (mono_error_set_pending_exception (&error))
6233 pklass = mono_ptr_class_get (type->type);
6235 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6236 mono_error_set_pending_exception (&error);
6241 ICALL_EXPORT MonoObject *
6242 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6243 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6246 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6247 MonoObject *delegate;
6249 MonoMethod *method = info->method;
6250 MonoMethodSignature *sig = mono_method_signature(method);
6252 mono_class_init_checked (delegate_class, &error);
6253 if (mono_error_set_pending_exception (&error))
6256 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6257 /* FIXME improve this exception message */
6258 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6260 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6261 mono_error_set_pending_exception (&error);
6265 if (mono_security_core_clr_enabled ()) {
6266 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6267 if (throwOnBindFailure)
6268 mono_error_set_pending_exception (&error);
6270 mono_error_cleanup (&error);
6275 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6276 if (!method->is_inflated) {
6277 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"));
6282 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6283 if (mono_error_set_pending_exception (&error))
6286 if (method_is_dynamic (method)) {
6287 /* Creating a trampoline would leak memory */
6288 func = mono_compile_method_checked (method, &error);
6289 if (mono_error_set_pending_exception (&error))
6292 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6293 method = mono_object_get_virtual_method (target, method);
6294 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6295 if (mono_error_set_pending_exception (&error))
6297 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6300 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6301 if (mono_error_set_pending_exception (&error))
6306 ICALL_EXPORT MonoMulticastDelegate *
6307 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6310 MonoMulticastDelegate *ret;
6312 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6314 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6315 if (mono_error_set_pending_exception (&error))
6318 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6323 ICALL_EXPORT MonoReflectionMethod*
6324 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6326 MonoReflectionMethod *ret = NULL;
6328 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6329 mono_error_set_pending_exception (&error);
6335 static inline gint32
6336 mono_array_get_byte_length (MonoArray *array)
6342 klass = array->obj.vtable->klass;
6344 if (array->bounds == NULL)
6345 length = array->max_length;
6348 for (i = 0; i < klass->rank; ++ i)
6349 length *= array->bounds [i].length;
6352 switch (klass->element_class->byval_arg.type) {
6355 case MONO_TYPE_BOOLEAN:
6359 case MONO_TYPE_CHAR:
6367 return length * sizeof (gpointer);
6378 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6380 return mono_array_get_byte_length (array);
6384 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6386 return mono_array_get (array, gint8, idx);
6390 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6392 mono_array_set (array, gint8, idx, value);
6395 ICALL_EXPORT MonoBoolean
6396 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6398 guint8 *src_buf, *dest_buf;
6401 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6405 g_assert (count >= 0);
6407 /* This is called directly from the class libraries without going through the managed wrapper */
6408 MONO_CHECK_ARG_NULL (src, FALSE);
6409 MONO_CHECK_ARG_NULL (dest, FALSE);
6411 /* watch out for integer overflow */
6412 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6415 src_buf = (guint8 *)src->vector + src_offset;
6416 dest_buf = (guint8 *)dest->vector + dest_offset;
6419 memcpy (dest_buf, src_buf, count);
6421 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6426 #ifndef DISABLE_REMOTING
6427 ICALL_EXPORT MonoObject *
6428 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6431 MonoDomain *domain = mono_object_domain (this_obj);
6433 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6434 MonoTransparentProxy *tp;
6438 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6439 if (mono_error_set_pending_exception (&error))
6442 tp = (MonoTransparentProxy*) res;
6444 MONO_OBJECT_SETREF (tp, rp, rp);
6445 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6446 klass = mono_class_from_mono_type (type);
6448 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6449 mono_class_setup_vtable (klass);
6450 if (mono_class_has_failure (klass)) {
6451 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6455 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6456 if (mono_error_set_pending_exception (&error))
6458 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6459 if (mono_error_set_pending_exception (&error))
6462 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6463 if (mono_error_set_pending_exception (&error))
6468 ICALL_EXPORT MonoReflectionType *
6469 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6472 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6473 mono_error_set_pending_exception (&error);
6479 /* System.Environment */
6482 ves_icall_System_Environment_get_UserName (void)
6484 /* using glib is more portable */
6485 return mono_string_new (mono_domain_get (), g_get_user_name ());
6490 mono_icall_get_machine_name (void)
6492 #if !defined(DISABLE_SOCKETS)
6496 #if defined _SC_HOST_NAME_MAX
6497 n = sysconf (_SC_HOST_NAME_MAX);
6501 buf = g_malloc (n+1);
6503 if (gethostname (buf, n) == 0){
6505 result = mono_string_new (mono_domain_get (), buf);
6512 return mono_string_new (mono_domain_get (), "mono");
6515 #endif /* !HOST_WIN32 */
6517 ICALL_EXPORT MonoString *
6518 ves_icall_System_Environment_get_MachineName (void)
6520 return mono_icall_get_machine_name ();
6525 mono_icall_get_platform (void)
6527 #if defined(__MACH__)
6530 // Notice that the value is hidden from user code, and only exposed
6531 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6532 // define and making assumptions based on Unix/128/4 values before there
6533 // was a MacOS define. Lots of code would assume that not-Unix meant
6534 // Windows, but in this case, it would be OSX.
6542 #endif /* !HOST_WIN32 */
6545 ves_icall_System_Environment_get_Platform (void)
6547 return mono_icall_get_platform ();
6551 static inline MonoString *
6552 mono_icall_get_new_line (void)
6554 return mono_string_new (mono_domain_get (), "\n");
6556 #endif /* !HOST_WIN32 */
6558 ICALL_EXPORT MonoString *
6559 ves_icall_System_Environment_get_NewLine (void)
6561 return mono_icall_get_new_line ();
6565 static inline MonoBoolean
6566 mono_icall_is_64bit_os (void)
6568 #if SIZEOF_VOID_P == 8
6571 #if defined(HAVE_SYS_UTSNAME_H)
6572 struct utsname name;
6574 if (uname (&name) >= 0) {
6575 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6581 #endif /* !HOST_WIN32 */
6583 ICALL_EXPORT MonoBoolean
6584 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6586 return mono_icall_is_64bit_os ();
6589 ICALL_EXPORT MonoStringHandle
6590 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6594 if (utf8_name == NULL)
6595 return NULL_HANDLE_STRING;
6597 value = g_getenv (utf8_name);
6600 return NULL_HANDLE_STRING;
6602 return mono_string_new_handle (mono_domain_get (), value, error);
6606 * There is no standard way to get at environ.
6609 #ifndef __MINGW32_VERSION
6610 #if defined(__APPLE__)
6611 #if defined (TARGET_OSX)
6612 /* Apple defines this in crt_externs.h but doesn't provide that header for
6613 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6614 * in fact exist on all implementations (so far)
6616 gchar ***_NSGetEnviron(void);
6617 #define environ (*_NSGetEnviron())
6619 static char *mono_environ[1] = { NULL };
6620 #define environ mono_environ
6621 #endif /* defined (TARGET_OSX) */
6629 ICALL_EXPORT MonoArray *
6630 ves_icall_System_Environment_GetCoomandLineArgs (void)
6633 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6634 mono_error_set_pending_exception (&error);
6640 mono_icall_get_environment_variable_names (void)
6650 for (e = environ; *e != 0; ++ e)
6653 domain = mono_domain_get ();
6654 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6655 if (mono_error_set_pending_exception (&error))
6659 for (e = environ; *e != 0; ++ e) {
6660 parts = g_strsplit (*e, "=", 2);
6662 str = mono_string_new (domain, *parts);
6663 mono_array_setref (names, n, str);
6673 #endif /* !HOST_WIN32 */
6675 ICALL_EXPORT MonoArray *
6676 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6678 return mono_icall_get_environment_variable_names ();
6683 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6685 gchar *utf8_name, *utf8_value;
6688 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6689 if (mono_error_set_pending_exception (&error))
6692 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6693 g_unsetenv (utf8_name);
6698 utf8_value = mono_string_to_utf8_checked (value, &error);
6699 if (!mono_error_ok (&error)) {
6701 mono_error_set_pending_exception (&error);
6704 g_setenv (utf8_name, utf8_value, TRUE);
6707 g_free (utf8_value);
6709 #endif /* !HOST_WIN32 */
6712 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6714 mono_icall_set_environment_variable (name, value);
6718 ves_icall_System_Environment_Exit (int result)
6720 mono_environment_exitcode_set (result);
6722 /* FIXME: There are some cleanup hangs that should be worked out, but
6723 * if the program is going to exit, everything will be cleaned up when
6724 * NaCl exits anyway.
6726 #ifndef __native_client__
6727 if (!mono_runtime_try_shutdown ())
6728 mono_thread_exit ();
6730 /* Suspend all managed threads since the runtime is going away */
6731 mono_thread_suspend_all_other_threads ();
6733 mono_runtime_quit ();
6736 /* we may need to do some cleanup here... */
6740 ICALL_EXPORT MonoStringHandle
6741 ves_icall_System_Environment_GetGacPath (MonoError *error)
6743 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6747 static inline MonoString *
6748 mono_icall_get_windows_folder_path (int folder)
6750 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6751 return mono_string_new (mono_domain_get (), "");
6753 #endif /* !HOST_WIN32 */
6755 ICALL_EXPORT MonoString*
6756 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6758 return mono_icall_get_windows_folder_path (folder);
6761 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6763 mono_icall_get_logical_drives (void)
6766 gunichar2 buf [256], *ptr, *dname;
6768 guint initial_size = 127, size = 128;
6771 MonoString *drivestr;
6772 MonoDomain *domain = mono_domain_get ();
6778 while (size > initial_size) {
6779 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6780 if (size > initial_size) {
6783 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6784 initial_size = size;
6798 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6799 if (mono_error_set_pending_exception (&error))
6806 while (*u16) { u16++; len ++; }
6807 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6808 if (mono_error_set_pending_exception (&error))
6811 mono_array_setref (result, ndrives++, drivestr);
6821 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6823 ICALL_EXPORT MonoArray *
6824 ves_icall_System_Environment_GetLogicalDrives (void)
6826 return mono_icall_get_logical_drives ();
6829 ICALL_EXPORT MonoString *
6830 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6833 gunichar2 volume_name [MAX_PATH + 1];
6835 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6837 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6838 mono_error_set_pending_exception (&error);
6842 ICALL_EXPORT MonoStringHandle
6843 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6845 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6848 static const char *encodings [] = {
6850 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6851 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6852 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6854 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6855 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6856 "x_unicode_2_0_utf_7",
6858 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6859 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6861 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6864 "unicodefffe", "utf_16be",
6871 * Returns the internal codepage, if the value of "int_code_page" is
6872 * 1 at entry, and we can not compute a suitable code page number,
6873 * returns the code page as a string
6875 ICALL_EXPORT MonoString*
6876 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6881 char *codepage = NULL;
6883 int want_name = *int_code_page;
6886 *int_code_page = -1;
6888 g_get_charset (&cset);
6889 c = codepage = g_strdup (cset);
6890 for (c = codepage; *c; c++){
6891 if (isascii (*c) && isalpha (*c))
6896 /* g_print ("charset: %s\n", cset); */
6898 /* handle some common aliases */
6901 for (i = 0; p != 0; ){
6904 p = encodings [++i];
6907 if (strcmp (p, codepage) == 0){
6908 *int_code_page = code;
6911 p = encodings [++i];
6914 if (strstr (codepage, "utf_8") != NULL)
6915 *int_code_page |= 0x10000000;
6918 if (want_name && *int_code_page == -1)
6919 return mono_string_new (mono_domain_get (), cset);
6924 ICALL_EXPORT MonoBoolean
6925 ves_icall_System_Environment_get_HasShutdownStarted (void)
6927 if (mono_runtime_is_shutting_down ())
6930 if (mono_domain_is_unloading (mono_domain_get ()))
6938 mono_icall_broadcast_setting_change (void)
6942 #endif /* !HOST_WIN32 */
6945 ves_icall_System_Environment_BroadcastSettingChange (void)
6947 mono_icall_broadcast_setting_change ();
6952 ves_icall_System_Environment_get_TickCount (void)
6954 /* this will overflow after ~24 days */
6955 return (gint32) (mono_msec_boottime () & 0xffffffff);
6959 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6964 #ifndef DISABLE_REMOTING
6965 ICALL_EXPORT MonoBoolean
6966 ves_icall_IsTransparentProxy (MonoObject *proxy)
6971 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6977 ICALL_EXPORT MonoReflectionMethod *
6978 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6979 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6981 MonoReflectionMethod *ret = NULL;
6986 MonoMethod **vtable;
6987 MonoMethod *res = NULL;
6989 MONO_CHECK_ARG_NULL (rtype, NULL);
6990 MONO_CHECK_ARG_NULL (rmethod, NULL);
6992 method = rmethod->method;
6993 klass = mono_class_from_mono_type (rtype->type);
6994 mono_class_init_checked (klass, &error);
6995 if (mono_error_set_pending_exception (&error))
6998 if (MONO_CLASS_IS_INTERFACE (klass))
7001 if (method->flags & METHOD_ATTRIBUTE_STATIC)
7004 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
7005 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
7011 mono_class_setup_vtable (klass);
7012 vtable = klass->vtable;
7014 if (mono_class_is_interface (method->klass)) {
7015 gboolean variance_used = FALSE;
7016 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
7017 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
7019 res = vtable [offs + method->slot];
7021 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
7024 if (method->slot != -1)
7025 res = vtable [method->slot];
7031 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
7032 mono_error_set_pending_exception (&error);
7037 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7043 klass = mono_class_from_mono_type (type->type);
7044 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
7045 if (!is_ok (&error)) {
7046 mono_error_set_pending_exception (&error);
7050 mono_vtable_set_is_remote (vtable, enable);
7053 #else /* DISABLE_REMOTING */
7056 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7058 g_assert_not_reached ();
7063 ICALL_EXPORT MonoObject *
7064 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
7071 domain = mono_object_domain (type);
7072 klass = mono_class_from_mono_type (type->type);
7073 mono_class_init_checked (klass, &error);
7074 if (mono_error_set_pending_exception (&error))
7077 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
7078 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
7082 if (klass->rank >= 1) {
7083 g_assert (klass->rank == 1);
7084 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
7085 mono_error_set_pending_exception (&error);
7088 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
7089 if (!is_ok (&error)) {
7090 mono_error_set_pending_exception (&error);
7093 /* Bypass remoting object creation check */
7094 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7095 mono_error_set_pending_exception (&error);
7101 ICALL_EXPORT MonoStringHandle
7102 ves_icall_System_IO_get_temp_path (MonoError *error)
7104 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7107 #ifndef PLATFORM_NO_DRIVEINFO
7108 ICALL_EXPORT MonoBoolean
7109 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7110 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7114 ULARGE_INTEGER wapi_free_bytes_avail;
7115 ULARGE_INTEGER wapi_total_number_of_bytes;
7116 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7118 *error = ERROR_SUCCESS;
7119 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7120 &wapi_total_number_of_free_bytes);
7123 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7124 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7125 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7127 *free_bytes_avail = 0;
7128 *total_number_of_bytes = 0;
7129 *total_number_of_free_bytes = 0;
7130 *error = GetLastError ();
7136 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7137 static inline guint32
7138 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7140 return GetDriveType (mono_string_chars (root_path_name));
7142 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7144 ICALL_EXPORT guint32
7145 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7147 return mono_icall_drive_info_get_drive_type (root_path_name);
7150 #endif /* PLATFORM_NO_DRIVEINFO */
7152 ICALL_EXPORT gpointer
7153 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7156 gpointer result = mono_compile_method_checked (method, &error);
7157 mono_error_set_pending_exception (&error);
7161 ICALL_EXPORT MonoString *
7162 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7167 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7169 mono_icall_make_platform_path (path);
7171 mcpath = mono_string_new (mono_domain_get (), path);
7177 /* this is an icall */
7179 get_bundled_app_config (void)
7182 const gchar *app_config;
7185 gchar *config_file_name, *config_file_path;
7186 gsize len, config_file_path_length, config_ext_length;
7189 domain = mono_domain_get ();
7190 file = domain->setup->configuration_file;
7191 if (!file || file->length == 0)
7194 // Retrieve config file and remove the extension
7195 config_file_name = mono_string_to_utf8_checked (file, &error);
7196 if (mono_error_set_pending_exception (&error))
7198 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7199 if (!config_file_path)
7200 config_file_path = config_file_name;
7202 config_file_path_length = strlen (config_file_path);
7203 config_ext_length = strlen (".config");
7204 if (config_file_path_length <= config_ext_length)
7207 len = config_file_path_length - config_ext_length;
7208 module = (gchar *)g_malloc0 (len + 1);
7209 memcpy (module, config_file_path, len);
7210 // Get the config file from the module name
7211 app_config = mono_config_string_for_assembly_file (module);
7214 if (config_file_name != config_file_path)
7215 g_free (config_file_name);
7216 g_free (config_file_path);
7221 return mono_string_new (mono_domain_get (), app_config);
7224 static MonoStringHandle
7225 get_bundled_machine_config (MonoError *error)
7227 const gchar *machine_config;
7229 machine_config = mono_get_machine_config ();
7231 if (!machine_config)
7232 return NULL_HANDLE_STRING;
7234 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7237 ICALL_EXPORT MonoStringHandle
7238 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7240 return get_bundled_machine_config (error);
7244 ICALL_EXPORT MonoStringHandle
7245 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7247 return get_bundled_machine_config (error);
7250 ICALL_EXPORT MonoStringHandle
7251 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7253 return get_bundled_machine_config (error);
7257 ICALL_EXPORT MonoString *
7258 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7263 path = g_path_get_dirname (mono_get_config_dir ());
7265 mono_icall_make_platform_path (path);
7267 ipath = mono_string_new (mono_domain_get (), path);
7273 ICALL_EXPORT gboolean
7274 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7276 MonoPEResourceDataEntry *entry;
7279 if (!assembly || !result || !size)
7284 image = assembly->assembly->image;
7285 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7289 *result = mono_image_rva_map (image, entry->rde_data_offset);
7294 *size = entry->rde_size;
7299 ICALL_EXPORT MonoBoolean
7300 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7302 return mono_is_debugger_attached ();
7305 ICALL_EXPORT MonoBoolean
7306 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7308 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7309 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7315 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7317 if (mono_get_runtime_callbacks ()->debug_log)
7318 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7323 mono_icall_write_windows_debug_string (MonoString *message)
7325 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7327 #endif /* !HOST_WIN32 */
7330 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7332 mono_icall_write_windows_debug_string (message);
7335 /* Only used for value types */
7336 ICALL_EXPORT MonoObject *
7337 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7344 domain = mono_object_domain (type);
7345 klass = mono_class_from_mono_type (type->type);
7346 mono_class_init_checked (klass, &error);
7347 if (mono_error_set_pending_exception (&error))
7350 if (mono_class_is_nullable (klass))
7351 /* No arguments -> null */
7354 result = mono_object_new_checked (domain, klass, &error);
7355 mono_error_set_pending_exception (&error);
7359 ICALL_EXPORT MonoReflectionMethod *
7360 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7362 MonoReflectionMethod *ret = NULL;
7365 MonoClass *klass, *parent;
7366 MonoGenericContext *generic_inst = NULL;
7367 MonoMethod *method = m->method;
7368 MonoMethod *result = NULL;
7371 if (method->klass == NULL)
7374 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7375 MONO_CLASS_IS_INTERFACE (method->klass) ||
7376 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7379 slot = mono_method_get_vtable_slot (method);
7383 klass = method->klass;
7384 if (mono_class_is_ginst (klass)) {
7385 generic_inst = mono_class_get_context (klass);
7386 klass = mono_class_get_generic_class (klass)->container_class;
7391 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7392 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7393 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7394 or klass is the generic container class and generic_inst is the instantiation.
7396 when we go to the parent, if the parent is an open constructed type, we need to
7397 replace the type parameters by the definitions from the generic_inst, and then take it
7398 apart again into the klass and the generic_inst.
7400 For cases like this:
7401 class C<T> : B<T, int> {
7402 public override void Foo () { ... }
7404 class B<U,V> : A<HashMap<U,V>> {
7405 public override void Foo () { ... }
7408 public virtual void Foo () { ... }
7411 if at each iteration the parent isn't open, we can skip inflating it. if at some
7412 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7415 MonoGenericContext *parent_inst = NULL;
7416 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7417 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7418 if (!mono_error_ok (&error)) {
7419 mono_error_set_pending_exception (&error);
7423 if (mono_class_is_ginst (parent)) {
7424 parent_inst = mono_class_get_context (parent);
7425 parent = mono_class_get_generic_class (parent)->container_class;
7428 mono_class_setup_vtable (parent);
7429 if (parent->vtable_size <= slot)
7432 generic_inst = parent_inst;
7435 klass = klass->parent;
7438 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7439 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7440 if (!mono_error_ok (&error)) {
7441 mono_error_set_pending_exception (&error);
7445 generic_inst = NULL;
7447 if (mono_class_is_ginst (klass)) {
7448 generic_inst = mono_class_get_context (klass);
7449 klass = mono_class_get_generic_class (klass)->container_class;
7455 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7456 if (!mono_error_ok (&error)) {
7457 mono_error_set_pending_exception (&error);
7462 if (klass == method->klass)
7465 /*This is possible if definition == FALSE.
7466 * Do it here to be really sure we don't read invalid memory.
7468 if (slot >= klass->vtable_size)
7471 mono_class_setup_vtable (klass);
7473 result = klass->vtable [slot];
7474 if (result == NULL) {
7475 /* It is an abstract method */
7476 gboolean found = FALSE;
7477 gpointer iter = NULL;
7478 while ((result = mono_class_get_methods (klass, &iter))) {
7479 if (result->slot == slot) {
7484 /* found might be FALSE if we looked in an abstract class
7485 * that doesn't override an abstract method of its
7487 * abstract class Base {
7488 * public abstract void Foo ();
7490 * abstract class Derived : Base { }
7491 * class Child : Derived {
7492 * public override void Foo () { }
7495 * if m was Child.Foo and we ask for the base method,
7496 * then we get here with klass == Derived and found == FALSE
7498 /* but it shouldn't be the case that if we're looking
7499 * for the definition and didn't find a result; the
7500 * loop above should've taken us as far as we could
7502 g_assert (!(definition && !found));
7507 g_assert (result != NULL);
7509 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7510 mono_error_set_pending_exception (&error);
7514 ICALL_EXPORT MonoString*
7515 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7517 MonoMethod *method = m->method;
7519 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7524 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7526 iter->sig = *(MonoMethodSignature**)argsp;
7528 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7529 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7532 /* FIXME: it's not documented what start is exactly... */
7536 iter->args = argsp + sizeof (gpointer);
7538 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7540 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7543 ICALL_EXPORT MonoTypedRef
7544 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7546 guint32 i, arg_size;
7550 i = iter->sig->sentinelpos + iter->next_arg;
7552 g_assert (i < iter->sig->param_count);
7554 res.type = iter->sig->params [i];
7555 res.klass = mono_class_from_mono_type (res.type);
7556 arg_size = mono_type_stack_size (res.type, &align);
7557 #if defined(__arm__) || defined(__mips__)
7558 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7560 res.value = iter->args;
7561 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7562 /* Values are stored as 8 byte register sized objects, but 'value'
7563 * is dereferenced as a pointer in other routines.
7565 res.value = (char*)res.value + 4;
7567 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7568 if (arg_size <= sizeof (gpointer)) {
7570 int padding = arg_size - mono_type_size (res.type, &dummy);
7571 res.value = (guint8*)res.value + padding;
7574 iter->args = (char*)iter->args + arg_size;
7577 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7582 ICALL_EXPORT MonoTypedRef
7583 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7585 guint32 i, arg_size;
7589 i = iter->sig->sentinelpos + iter->next_arg;
7591 g_assert (i < iter->sig->param_count);
7593 while (i < iter->sig->param_count) {
7594 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7596 res.type = iter->sig->params [i];
7597 res.klass = mono_class_from_mono_type (res.type);
7598 /* FIXME: endianess issue... */
7599 arg_size = mono_type_stack_size (res.type, &align);
7600 #if defined(__arm__) || defined(__mips__)
7601 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7603 res.value = iter->args;
7604 iter->args = (char*)iter->args + arg_size;
7606 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7609 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7617 ICALL_EXPORT MonoType*
7618 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7622 i = iter->sig->sentinelpos + iter->next_arg;
7624 g_assert (i < iter->sig->param_count);
7626 return iter->sig->params [i];
7629 ICALL_EXPORT MonoObject*
7630 mono_TypedReference_ToObject (MonoTypedRef* tref)
7633 MonoObject *result = NULL;
7634 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7635 MonoObject** objp = (MonoObject **)tref->value;
7639 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7640 mono_error_set_pending_exception (&error);
7644 ICALL_EXPORT MonoTypedRef
7645 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7648 MonoReflectionField *f;
7650 MonoType *ftype = NULL;
7654 memset (&res, 0, sizeof (res));
7657 g_assert (mono_array_length (fields) > 0);
7659 klass = target->vtable->klass;
7661 for (i = 0; i < mono_array_length (fields); ++i) {
7662 f = mono_array_get (fields, MonoReflectionField*, i);
7664 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7667 if (f->field->parent != klass) {
7668 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7672 p = (guint8*)target + f->field->offset;
7674 p += f->field->offset - sizeof (MonoObject);
7675 klass = mono_class_from_mono_type (f->field->type);
7676 ftype = f->field->type;
7680 res.klass = mono_class_from_mono_type (ftype);
7687 prelink_method (MonoMethod *method, MonoError *error)
7689 const char *exc_class, *exc_arg;
7691 mono_error_init (error);
7692 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7694 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7696 mono_error_set_exception_instance (error,
7697 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7700 /* create the wrapper, too? */
7704 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7708 prelink_method (method->method, &error);
7709 mono_error_set_pending_exception (&error);
7713 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7716 MonoClass *klass = mono_class_from_mono_type (type->type);
7718 gpointer iter = NULL;
7720 mono_class_init_checked (klass, &error);
7721 if (mono_error_set_pending_exception (&error))
7724 while ((m = mono_class_get_methods (klass, &iter))) {
7725 prelink_method (m, &error);
7726 if (mono_error_set_pending_exception (&error))
7731 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7733 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7734 gint32 const **exponents,
7735 gunichar2 const **digitLowerTable,
7736 gunichar2 const **digitUpperTable,
7737 gint64 const **tenPowersList,
7738 gint32 const **decHexDigits)
7740 *mantissas = Formatter_MantissaBitsTable;
7741 *exponents = Formatter_TensExponentTable;
7742 *digitLowerTable = Formatter_DigitLowerTable;
7743 *digitUpperTable = Formatter_DigitUpperTable;
7744 *tenPowersList = Formatter_TenPowersList;
7745 *decHexDigits = Formatter_DecHexDigits;
7749 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7750 * and avoid useless allocations.
7753 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7755 MonoReflectionType *rt;
7759 mono_error_init (error);
7760 for (i = 0; i < type->num_mods; ++i) {
7761 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7766 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7767 return_val_if_nok (error, NULL);
7769 for (i = 0; i < type->num_mods; ++i) {
7770 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7771 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7772 return_val_if_nok (error, NULL);
7774 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7775 return_val_if_nok (error, NULL);
7777 mono_array_setref (res, count, rt);
7784 ICALL_EXPORT MonoArray*
7785 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7788 MonoType *type = param->ClassImpl->type;
7789 MonoClass *member_class = mono_object_class (param->MemberImpl);
7790 MonoMethod *method = NULL;
7793 MonoMethodSignature *sig;
7796 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7797 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7798 method = rmethod->method;
7799 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7800 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7801 if (!(method = prop->property->get))
7802 method = prop->property->set;
7805 char *type_name = mono_type_get_full_name (member_class);
7806 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7807 MonoException *ex = mono_get_exception_not_supported (msg);
7810 mono_set_pending_exception (ex);
7814 image = method->klass->image;
7815 pos = param->PositionImpl;
7816 sig = mono_method_signature (method);
7820 type = sig->params [pos];
7822 res = type_array_from_modifiers (image, type, optional, &error);
7823 mono_error_set_pending_exception (&error);
7828 get_property_type (MonoProperty *prop)
7830 MonoMethodSignature *sig;
7832 sig = mono_method_signature (prop->get);
7834 } else if (prop->set) {
7835 sig = mono_method_signature (prop->set);
7836 return sig->params [sig->param_count - 1];
7841 ICALL_EXPORT MonoArray*
7842 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7845 MonoType *type = get_property_type (property->property);
7846 MonoImage *image = property->klass->image;
7851 res = type_array_from_modifiers (image, type, optional, &error);
7852 mono_error_set_pending_exception (&error);
7857 *Construct a MonoType suited to be used to decode a constant blob object.
7859 * @type is the target type which will be constructed
7860 * @blob_type is the blob type, for example, that comes from the constant table
7861 * @real_type is the expected constructed type.
7864 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7866 type->type = blob_type;
7867 type->data.klass = NULL;
7868 if (blob_type == MONO_TYPE_CLASS)
7869 type->data.klass = mono_defaults.object_class;
7870 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7871 /* For enums, we need to use the base type */
7872 type->type = MONO_TYPE_VALUETYPE;
7873 type->data.klass = mono_class_from_mono_type (real_type);
7875 type->data.klass = mono_class_from_mono_type (real_type);
7878 ICALL_EXPORT MonoObject*
7879 property_info_get_default_value (MonoReflectionProperty *property)
7883 MonoProperty *prop = property->property;
7884 MonoType *type = get_property_type (prop);
7885 MonoDomain *domain = mono_object_domain (property);
7886 MonoTypeEnum def_type;
7887 const char *def_value;
7890 mono_class_init (prop->parent);
7892 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7893 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7897 def_value = mono_class_get_property_default_value (prop, &def_type);
7899 mono_type_from_blob_type (&blob_type, def_type, type);
7900 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7902 mono_error_set_pending_exception (&error);
7906 ICALL_EXPORT MonoBoolean
7907 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7910 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7911 MonoCustomAttrInfo *cinfo;
7914 mono_class_init_checked (attr_class, &error);
7915 if (mono_error_set_pending_exception (&error))
7918 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7919 if (!is_ok (&error)) {
7920 mono_error_set_pending_exception (&error);
7925 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7927 mono_custom_attrs_free (cinfo);
7931 ICALL_EXPORT MonoArray*
7932 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7934 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7939 mono_class_init_checked (attr_class, &error);
7940 if (mono_error_set_pending_exception (&error))
7944 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7945 if (!mono_error_ok (&error)) {
7946 mono_error_set_pending_exception (&error);
7953 ICALL_EXPORT MonoArray*
7954 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7958 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7959 mono_error_set_pending_exception (&error);
7964 ICALL_EXPORT MonoStringHandle
7965 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7968 MonoStringHandle display_name;
7970 mono_error_init (error);
7971 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7972 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7974 return display_name;
7977 ICALL_EXPORT MonoString*
7978 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7981 MonoString *message;
7985 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7986 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7989 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7991 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7992 if (mono_error_set_pending_exception (&error))
8000 static inline gint32
8001 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
8003 return WAIT_TIMEOUT;
8005 #endif /* !HOST_WIN32 */
8008 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
8010 return mono_icall_wait_for_input_idle (handle, milliseconds);
8014 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
8016 return mono_process_current_pid ();
8019 ICALL_EXPORT MonoBoolean
8020 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
8032 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
8034 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
8038 ICALL_EXPORT MonoObject*
8039 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
8041 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
8046 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
8048 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
8052 ICALL_EXPORT MonoObject*
8053 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
8055 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
8059 ICALL_EXPORT MonoBoolean
8060 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
8062 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
8067 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
8069 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
8073 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
8075 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
8080 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
8082 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
8086 ICALL_EXPORT mono_unichar2*
8087 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
8089 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
8096 #ifndef DISABLE_ICALL_TABLES
8098 #define ICALL_TYPE(id,name,first)
8099 #define ICALL(id,name,func) Icall_ ## id,
8100 #define HANDLES(inner) inner
8103 #include "metadata/icall-def.h"
8109 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8110 #define ICALL(id,name,func)
8112 #define HANDLES(inner) inner
8114 #include "metadata/icall-def.h"
8120 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8121 #define ICALL(id,name,func)
8123 #define HANDLES(inner) inner
8125 guint16 first_icall;
8128 static const IcallTypeDesc
8129 icall_type_descs [] = {
8130 #include "metadata/icall-def.h"
8134 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8137 #define HANDLES(inner) inner
8139 #define ICALL_TYPE(id,name,first)
8142 #ifdef HAVE_ARRAY_ELEM_INIT
8143 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8144 #define MSGSTRFIELD1(line) str##line
8146 static const struct msgstrtn_t {
8147 #define ICALL(id,name,func)
8149 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8150 #include "metadata/icall-def.h"
8152 } icall_type_names_str = {
8153 #define ICALL_TYPE(id,name,first) (name),
8154 #include "metadata/icall-def.h"
8157 static const guint16 icall_type_names_idx [] = {
8158 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8159 #include "metadata/icall-def.h"
8162 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8164 static const struct msgstr_t {
8166 #define ICALL_TYPE(id,name,first)
8167 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8168 #include "metadata/icall-def.h"
8170 } icall_names_str = {
8171 #define ICALL(id,name,func) (name),
8172 #include "metadata/icall-def.h"
8175 static const guint16 icall_names_idx [] = {
8176 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8177 #include "metadata/icall-def.h"
8180 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8186 #define ICALL_TYPE(id,name,first) name,
8187 #define ICALL(id,name,func)
8188 static const char* const
8189 icall_type_names [] = {
8190 #include "metadata/icall-def.h"
8194 #define icall_type_name_get(id) (icall_type_names [(id)])
8198 #define ICALL_TYPE(id,name,first)
8199 #define ICALL(id,name,func) name,
8200 static const char* const
8202 #include "metadata/icall-def.h"
8205 #define icall_name_get(id) icall_names [(id)]
8207 #endif /* !HAVE_ARRAY_ELEM_INIT */
8210 #define HANDLES(inner) inner
8213 #define ICALL_TYPE(id,name,first)
8214 #define ICALL(id,name,func) func,
8215 static const gconstpointer
8216 icall_functions [] = {
8217 #include "metadata/icall-def.h"
8221 #ifdef ENABLE_ICALL_SYMBOL_MAP
8223 #define HANDLES(inner) inner
8226 #define ICALL_TYPE(id,name,first)
8227 #define ICALL(id,name,func) #func,
8228 static const gconstpointer
8229 icall_symbols [] = {
8230 #include "metadata/icall-def.h"
8237 #define ICALL_TYPE(id,name,first)
8238 #define ICALL(id,name,func) 0,
8240 #define HANDLES(inner) 1,
8242 icall_uses_handles [] = {
8243 #include "metadata/icall-def.h"
8248 #endif /* DISABLE_ICALL_TABLES */
8250 static mono_mutex_t icall_mutex;
8251 static GHashTable *icall_hash = NULL;
8252 static GHashTable *jit_icall_hash_name = NULL;
8253 static GHashTable *jit_icall_hash_addr = NULL;
8256 mono_icall_init (void)
8258 #ifndef DISABLE_ICALL_TABLES
8261 /* check that tables are sorted: disable in release */
8264 const char *prev_class = NULL;
8265 const char *prev_method;
8267 for (i = 0; i < Icall_type_num; ++i) {
8268 const IcallTypeDesc *desc;
8271 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8272 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8273 prev_class = icall_type_name_get (i);
8274 desc = &icall_type_descs [i];
8275 num_icalls = icall_desc_num_icalls (desc);
8276 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8277 for (j = 0; j < num_icalls; ++j) {
8278 const char *methodn = icall_name_get (desc->first_icall + j);
8279 if (prev_method && strcmp (prev_method, methodn) >= 0)
8280 g_print ("method %s should come before method %s\n", methodn, prev_method);
8281 prev_method = methodn;
8287 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8288 mono_os_mutex_init (&icall_mutex);
8292 mono_icall_lock (void)
8294 mono_locks_os_acquire (&icall_mutex, IcallLock);
8298 mono_icall_unlock (void)
8300 mono_locks_os_release (&icall_mutex, IcallLock);
8304 mono_icall_cleanup (void)
8306 g_hash_table_destroy (icall_hash);
8307 g_hash_table_destroy (jit_icall_hash_name);
8308 g_hash_table_destroy (jit_icall_hash_addr);
8309 mono_os_mutex_destroy (&icall_mutex);
8313 * mono_add_internal_call:
8314 * @name: method specification to surface to the managed world
8315 * @method: pointer to a C method to invoke when the method is called
8317 * This method surfaces the C function pointed by @method as a method
8318 * that has been surfaced in managed code with the method specified in
8319 * @name as an internal call.
8321 * Internal calls are surfaced to all app domains loaded and they are
8322 * accessibly by a type with the specified name.
8324 * You must provide a fully qualified type name, that is namespaces
8325 * and type name, followed by a colon and the method name, with an
8326 * optional signature to bind.
8328 * For example, the following are all valid declarations:
8330 * "MyApp.Services.ScriptService:Accelerate"
8331 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8333 * You use method parameters in cases where there might be more than
8334 * one surface method to managed code. That way you can register different
8335 * internal calls for different method overloads.
8337 * The internal calls are invoked with no marshalling. This means that .NET
8338 * types like System.String are exposed as `MonoString *` parameters. This is
8339 * different than the way that strings are surfaced in P/Invoke.
8341 * For more information on how the parameters are marshalled, see the
8342 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8345 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8346 * reference for more information on the format of method descriptions.
8349 mono_add_internal_call (const char *name, gconstpointer method)
8353 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8355 mono_icall_unlock ();
8358 #ifndef DISABLE_ICALL_TABLES
8360 #ifdef HAVE_ARRAY_ELEM_INIT
8362 compare_method_imap (const void *key, const void *elem)
8364 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8365 return strcmp (key, method_name);
8369 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8371 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);
8374 return (nameslot - &icall_names_idx [0]);
8378 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8380 gsize slotnum = find_slot_icall (imap, name);
8383 return (gboolean)icall_uses_handles [slotnum];
8387 find_method_icall (const IcallTypeDesc *imap, const char *name)
8389 gsize slotnum = find_slot_icall (imap, name);
8392 return (gpointer)icall_functions [slotnum];
8396 compare_class_imap (const void *key, const void *elem)
8398 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8399 return strcmp (key, class_name);
8402 static const IcallTypeDesc*
8403 find_class_icalls (const char *name)
8405 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);
8408 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8411 #else /* HAVE_ARRAY_ELEM_INIT */
8414 compare_method_imap (const void *key, const void *elem)
8416 const char** method_name = (const char**)elem;
8417 return strcmp (key, *method_name);
8421 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8423 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8426 return nameslot - icall_names;
8430 find_method_icall (const IcallTypeDesc *imap, const char *name)
8432 gsize slotnum = find_slot_icall (imap, name);
8435 return (gpointer)icall_functions [slotnum];
8439 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8441 gsize slotnum = find_slot_icall (imap, name);
8444 return (gboolean)icall_uses_handles [slotnum];
8448 compare_class_imap (const void *key, const void *elem)
8450 const char** class_name = (const char**)elem;
8451 return strcmp (key, *class_name);
8454 static const IcallTypeDesc*
8455 find_class_icalls (const char *name)
8457 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8460 return &icall_type_descs [nameslot - icall_type_names];
8463 #endif /* HAVE_ARRAY_ELEM_INIT */
8465 #endif /* DISABLE_ICALL_TABLES */
8468 * we should probably export this as an helper (handle nested types).
8469 * Returns the number of chars written in buf.
8472 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8474 int nspacelen, cnamelen;
8475 nspacelen = strlen (klass->name_space);
8476 cnamelen = strlen (klass->name);
8477 if (nspacelen + cnamelen + 2 > bufsize)
8480 memcpy (buf, klass->name_space, nspacelen);
8481 buf [nspacelen ++] = '.';
8483 memcpy (buf + nspacelen, klass->name, cnamelen);
8484 buf [nspacelen + cnamelen] = 0;
8485 return nspacelen + cnamelen;
8488 #ifdef DISABLE_ICALL_TABLES
8490 no_icall_table (void)
8492 g_assert_not_reached ();
8497 * mono_lookup_internal_call_full:
8498 * @method: the method to look up
8499 * @uses_handles: out argument if method needs handles around managed objects.
8501 * Returns a pointer to the icall code for the given method. If
8502 * uses_handles is not NULL, it will be set to TRUE if the method
8503 * needs managed objects wrapped using the infrastructure in handle.h
8505 * If the method is not found, warns and returns NULL.
8508 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8513 int typelen = 0, mlen, siglen;
8515 #ifndef DISABLE_ICALL_TABLES
8516 const IcallTypeDesc *imap = NULL;
8519 g_assert (method != NULL);
8521 if (method->is_inflated)
8522 method = ((MonoMethodInflated *) method)->declaring;
8524 if (method->klass->nested_in) {
8525 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8529 mname [pos++] = '/';
8532 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8538 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8543 #ifndef DISABLE_ICALL_TABLES
8544 imap = find_class_icalls (mname);
8547 mname [typelen] = ':';
8548 mname [typelen + 1] = ':';
8550 mlen = strlen (method->name);
8551 memcpy (mname + typelen + 2, method->name, mlen);
8552 sigstart = mname + typelen + 2 + mlen;
8555 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8556 siglen = strlen (tmpsig);
8557 if (typelen + mlen + siglen + 6 > sizeof (mname))
8560 memcpy (sigstart + 1, tmpsig, siglen);
8561 sigstart [siglen + 1] = ')';
8562 sigstart [siglen + 2] = 0;
8567 res = g_hash_table_lookup (icall_hash, mname);
8570 *uses_handles = FALSE;
8571 mono_icall_unlock ();;
8574 /* try without signature */
8576 res = g_hash_table_lookup (icall_hash, mname);
8579 *uses_handles = FALSE;
8580 mono_icall_unlock ();
8584 #ifdef DISABLE_ICALL_TABLES
8585 mono_icall_unlock ();
8586 /* Fail only when the result is actually used */
8587 /* mono_marshal_get_native_wrapper () depends on this */
8588 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8589 return ves_icall_System_String_ctor_RedirectToCreateString;
8591 return no_icall_table;
8593 /* it wasn't found in the static call tables */
8596 *uses_handles = FALSE;
8597 mono_icall_unlock ();
8600 res = find_method_icall (imap, sigstart - mlen);
8603 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8604 mono_icall_unlock ();
8607 /* try _with_ signature */
8609 res = find_method_icall (imap, sigstart - mlen);
8612 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8613 mono_icall_unlock ();
8617 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8618 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8619 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8620 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8621 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");
8622 g_print ("If you see other errors or faults after this message they are probably related\n");
8623 g_print ("and you need to fix your mono install first.\n");
8625 mono_icall_unlock ();
8632 mono_lookup_internal_call (MonoMethod *method)
8634 return mono_lookup_internal_call_full (method, NULL);
8637 #ifdef ENABLE_ICALL_SYMBOL_MAP
8639 func_cmp (gconstpointer key, gconstpointer p)
8641 return (gsize)key - (gsize)*(gsize*)p;
8646 * mono_lookup_icall_symbol:
8648 * Given the icall METHOD, returns its C symbol.
8651 mono_lookup_icall_symbol (MonoMethod *m)
8653 #ifdef DISABLE_ICALL_TABLES
8654 g_assert_not_reached ();
8657 #ifdef ENABLE_ICALL_SYMBOL_MAP
8661 static gconstpointer *functions_sorted;
8662 static const char**symbols_sorted;
8663 static gboolean inited;
8668 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8669 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8670 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8671 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8672 /* Bubble sort the two arrays */
8676 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8677 if (functions_sorted [i] > functions_sorted [i + 1]) {
8680 tmp = functions_sorted [i];
8681 functions_sorted [i] = functions_sorted [i + 1];
8682 functions_sorted [i + 1] = tmp;
8683 tmp = symbols_sorted [i];
8684 symbols_sorted [i] = symbols_sorted [i + 1];
8685 symbols_sorted [i + 1] = tmp;
8692 func = mono_lookup_internal_call (m);
8695 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8699 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8701 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8702 g_assert_not_reached ();
8709 type_from_typename (char *type_name)
8711 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8713 if (!strcmp (type_name, "int"))
8714 klass = mono_defaults.int_class;
8715 else if (!strcmp (type_name, "ptr"))
8716 klass = mono_defaults.int_class;
8717 else if (!strcmp (type_name, "void"))
8718 klass = mono_defaults.void_class;
8719 else if (!strcmp (type_name, "int32"))
8720 klass = mono_defaults.int32_class;
8721 else if (!strcmp (type_name, "uint32"))
8722 klass = mono_defaults.uint32_class;
8723 else if (!strcmp (type_name, "int8"))
8724 klass = mono_defaults.sbyte_class;
8725 else if (!strcmp (type_name, "uint8"))
8726 klass = mono_defaults.byte_class;
8727 else if (!strcmp (type_name, "int16"))
8728 klass = mono_defaults.int16_class;
8729 else if (!strcmp (type_name, "uint16"))
8730 klass = mono_defaults.uint16_class;
8731 else if (!strcmp (type_name, "long"))
8732 klass = mono_defaults.int64_class;
8733 else if (!strcmp (type_name, "ulong"))
8734 klass = mono_defaults.uint64_class;
8735 else if (!strcmp (type_name, "float"))
8736 klass = mono_defaults.single_class;
8737 else if (!strcmp (type_name, "double"))
8738 klass = mono_defaults.double_class;
8739 else if (!strcmp (type_name, "object"))
8740 klass = mono_defaults.object_class;
8741 else if (!strcmp (type_name, "obj"))
8742 klass = mono_defaults.object_class;
8743 else if (!strcmp (type_name, "string"))
8744 klass = mono_defaults.string_class;
8745 else if (!strcmp (type_name, "bool"))
8746 klass = mono_defaults.boolean_class;
8747 else if (!strcmp (type_name, "boolean"))
8748 klass = mono_defaults.boolean_class;
8750 g_error ("%s", type_name);
8751 g_assert_not_reached ();
8753 return &klass->byval_arg;
8757 * LOCKING: Take the corlib image lock.
8759 MonoMethodSignature*
8760 mono_create_icall_signature (const char *sigstr)
8765 MonoMethodSignature *res, *res2;
8766 MonoImage *corlib = mono_defaults.corlib;
8768 mono_image_lock (corlib);
8769 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8770 mono_image_unlock (corlib);
8775 parts = g_strsplit (sigstr, " ", 256);
8784 res = mono_metadata_signature_alloc (corlib, len - 1);
8789 * Under windows, the default pinvoke calling convention is STDCALL but
8792 res->call_convention = MONO_CALL_C;
8795 res->ret = type_from_typename (parts [0]);
8796 for (i = 1; i < len; ++i) {
8797 res->params [i - 1] = type_from_typename (parts [i]);
8802 mono_image_lock (corlib);
8803 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8805 res = res2; /*Value is allocated in the image pool*/
8807 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8808 mono_image_unlock (corlib);
8814 mono_find_jit_icall_by_name (const char *name)
8816 MonoJitICallInfo *info;
8817 g_assert (jit_icall_hash_name);
8820 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8821 mono_icall_unlock ();
8826 mono_find_jit_icall_by_addr (gconstpointer addr)
8828 MonoJitICallInfo *info;
8829 g_assert (jit_icall_hash_addr);
8832 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8833 mono_icall_unlock ();
8839 * mono_get_jit_icall_info:
8841 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8842 * caller should access it while holding the icall lock.
8845 mono_get_jit_icall_info (void)
8847 return jit_icall_hash_name;
8851 * mono_lookup_jit_icall_symbol:
8853 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8856 mono_lookup_jit_icall_symbol (const char *name)
8858 MonoJitICallInfo *info;
8859 const char *res = NULL;
8862 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8864 res = info->c_symbol;
8865 mono_icall_unlock ();
8870 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8873 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8874 mono_icall_unlock ();
8878 * 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
8879 * icalls without wrappers in some cases.
8882 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8884 MonoJitICallInfo *info;
8891 if (!jit_icall_hash_name) {
8892 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8893 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8896 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8897 g_warning ("jit icall already defined \"%s\"\n", name);
8898 g_assert_not_reached ();
8901 info = g_new0 (MonoJitICallInfo, 1);
8906 info->c_symbol = c_symbol;
8907 info->no_raise = no_raise;
8910 info->wrapper = func;
8912 info->wrapper = NULL;
8915 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8916 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8918 mono_icall_unlock ();
8923 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8925 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);