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_get_underlying_type_ignore_byref (MonoType *type)
1597 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1598 return mono_class_enum_basetype (type->data.klass);
1599 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1600 return mono_class_enum_basetype (type->data.generic_class->container_class);
1604 ICALL_EXPORT guint32
1605 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1610 g_assert (type != NULL);
1612 klass = mono_class_from_mono_type (type->type);
1613 klassc = mono_class_from_mono_type (c->type);
1615 if (type->type->byref ^ c->type->byref)
1618 if (type->type->byref) {
1619 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1620 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1622 klass = mono_class_from_mono_type (t);
1623 klassc = mono_class_from_mono_type (ot);
1625 if (mono_type_is_primitive (t)) {
1626 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1627 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1628 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1629 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1630 return t->type == ot->type;
1632 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1635 if (klass->valuetype)
1636 return klass == klassc;
1637 return klass->valuetype == klassc->valuetype;
1640 return mono_class_is_assignable_from (klass, klassc);
1643 ICALL_EXPORT guint32
1644 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1647 MonoClass *klass = mono_class_from_mono_type (type->type);
1648 mono_class_init_checked (klass, &error);
1649 if (!is_ok (&error)) {
1650 mono_error_set_pending_exception (&error);
1653 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1654 mono_error_set_pending_exception (&error);
1658 ICALL_EXPORT guint32
1659 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1661 MonoClass *klass = mono_class_from_mono_type (type->type);
1662 return mono_class_get_flags (klass);
1665 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1666 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1669 MonoClass *klass = field->field->parent;
1670 MonoMarshalType *info;
1674 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1675 if (mono_class_is_gtd (klass) ||
1676 (gklass && gklass->context.class_inst->is_open))
1679 ftype = mono_field_get_type (field->field);
1680 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1683 info = mono_marshal_load_type_info (klass);
1685 for (i = 0; i < info->num_fields; ++i) {
1686 if (info->fields [i].field == field->field) {
1687 if (!info->fields [i].mspec)
1690 MonoReflectionMarshalAsAttribute* obj;
1691 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1692 if (!mono_error_ok (&error))
1693 mono_error_set_pending_exception (&error);
1702 ICALL_EXPORT MonoReflectionField*
1703 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1706 gboolean found = FALSE;
1712 klass = handle->parent;
1714 klass = mono_class_from_mono_type (type);
1716 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1719 /* The managed code will throw the exception */
1723 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1724 mono_error_set_pending_exception (&error);
1728 ICALL_EXPORT MonoReflectionEvent*
1729 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1737 klass = handle->parent;
1739 klass = mono_class_from_mono_type (type);
1741 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1743 /* Managed code will throw an exception */
1747 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1748 mono_error_set_pending_exception (&error);
1753 ICALL_EXPORT MonoReflectionProperty*
1754 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1762 klass = handle->parent;
1764 klass = mono_class_from_mono_type (type);
1766 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1768 /* Managed code will throw an exception */
1772 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1773 mono_error_set_pending_exception (&error);
1777 ICALL_EXPORT MonoArray*
1778 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1781 MonoType *type = mono_field_get_type_checked (field->field, &error);
1784 if (!mono_error_ok (&error)) {
1785 mono_error_set_pending_exception (&error);
1789 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1790 mono_error_set_pending_exception (&error);
1795 vell_icall_get_method_attributes (MonoMethod *method)
1797 return method->flags;
1801 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1804 MonoReflectionType *rt;
1805 MonoDomain *domain = mono_domain_get ();
1806 MonoMethodSignature* sig;
1808 sig = mono_method_signature_checked (method, &error);
1809 if (!mono_error_ok (&error)) {
1810 mono_error_set_pending_exception (&error);
1814 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1815 if (!mono_error_ok (&error)) {
1816 mono_error_set_pending_exception (&error);
1820 MONO_STRUCT_SETREF (info, parent, rt);
1822 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1823 if (!mono_error_ok (&error)) {
1824 mono_error_set_pending_exception (&error);
1828 MONO_STRUCT_SETREF (info, ret, rt);
1830 info->attrs = method->flags;
1831 info->implattrs = method->iflags;
1832 if (sig->call_convention == MONO_CALL_DEFAULT)
1833 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1835 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1840 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1843 ICALL_EXPORT MonoArray*
1844 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1847 MonoDomain *domain = mono_domain_get ();
1849 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1850 mono_error_set_pending_exception (&error);
1854 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1855 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1858 MonoDomain *domain = mono_domain_get ();
1859 MonoReflectionMarshalAsAttribute* res = NULL;
1860 MonoMarshalSpec **mspecs;
1863 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1864 mono_method_get_marshal_info (method, mspecs);
1867 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1868 if (!mono_error_ok (&error)) {
1869 mono_error_set_pending_exception (&error);
1874 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1876 mono_metadata_free_marshal_spec (mspecs [i]);
1883 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1885 MonoClass *parent = field->field->parent;
1886 mono_class_setup_fields (parent);
1888 return field->field->offset - sizeof (MonoObject);
1891 ICALL_EXPORT MonoReflectionType*
1892 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1895 MonoReflectionType *ret;
1898 parent = declaring? field->field->parent: field->klass;
1900 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1901 mono_error_set_pending_exception (&error);
1907 ICALL_EXPORT MonoObject *
1908 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1911 MonoClass *fklass = field->klass;
1912 MonoClassField *cf = field->field;
1913 MonoDomain *domain = mono_object_domain (field);
1915 if (fklass->image->assembly->ref_only) {
1916 mono_set_pending_exception (mono_get_exception_invalid_operation (
1917 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1921 if (mono_security_core_clr_enabled () &&
1922 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1923 mono_error_set_pending_exception (&error);
1927 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1928 mono_error_set_pending_exception (&error);
1933 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1936 MonoClassField *cf = field->field;
1940 if (field->klass->image->assembly->ref_only) {
1941 mono_set_pending_exception (mono_get_exception_invalid_operation (
1942 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1946 if (mono_security_core_clr_enabled () &&
1947 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1948 mono_error_set_pending_exception (&error);
1952 type = mono_field_get_type_checked (cf, &error);
1953 if (!mono_error_ok (&error)) {
1954 mono_error_set_pending_exception (&error);
1958 v = (gchar *) value;
1960 switch (type->type) {
1963 case MONO_TYPE_BOOLEAN:
1966 case MONO_TYPE_CHAR:
1975 case MONO_TYPE_VALUETYPE:
1978 v += sizeof (MonoObject);
1980 case MONO_TYPE_STRING:
1981 case MONO_TYPE_OBJECT:
1982 case MONO_TYPE_CLASS:
1983 case MONO_TYPE_ARRAY:
1984 case MONO_TYPE_SZARRAY:
1987 case MONO_TYPE_GENERICINST: {
1988 MonoGenericClass *gclass = type->data.generic_class;
1989 g_assert (!gclass->context.class_inst->is_open);
1991 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1992 MonoClass *nklass = mono_class_from_mono_type (type);
1993 MonoObject *nullable;
1996 * Convert the boxed vtype into a Nullable structure.
1997 * This is complicated by the fact that Nullables have
1998 * a variable structure.
2000 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2001 if (!mono_error_ok (&error)) {
2002 mono_error_set_pending_exception (&error);
2006 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2008 v = (gchar *)mono_object_unbox (nullable);
2011 if (gclass->container_class->valuetype && (v != NULL))
2012 v += sizeof (MonoObject);
2016 g_error ("type 0x%x not handled in "
2017 "ves_icall_FieldInfo_SetValueInternal", type->type);
2022 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2023 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2024 if (!is_ok (&error)) {
2025 mono_error_set_pending_exception (&error);
2028 if (!vtable->initialized) {
2029 if (!mono_runtime_class_init_full (vtable, &error)) {
2030 mono_error_set_pending_exception (&error);
2034 mono_field_static_set_value (vtable, cf, v);
2036 mono_field_set_value (obj, cf, v);
2041 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2050 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2051 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2055 if (MONO_TYPE_IS_REFERENCE (f->type))
2056 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2058 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2061 ICALL_EXPORT MonoObject *
2062 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2064 MonoObject *o = NULL;
2065 MonoClassField *field = rfield->field;
2067 MonoDomain *domain = mono_object_domain (rfield);
2069 MonoTypeEnum def_type;
2070 const char *def_value;
2074 mono_class_init (field->parent);
2076 t = mono_field_get_type_checked (field, &error);
2077 if (!mono_error_ok (&error)) {
2078 mono_error_set_pending_exception (&error);
2082 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2083 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2087 if (image_is_dynamic (field->parent->image)) {
2088 MonoClass *klass = field->parent;
2089 int fidx = field - klass->fields;
2090 MonoClassExt *ext = mono_class_get_ext (klass);
2093 g_assert (ext->field_def_values);
2094 def_type = ext->field_def_values [fidx].def_type;
2095 def_value = ext->field_def_values [fidx].data;
2097 if (def_type == MONO_TYPE_END) {
2098 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2102 def_value = mono_class_get_field_default_value (field, &def_type);
2103 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2105 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2110 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2114 case MONO_TYPE_BOOLEAN:
2117 case MONO_TYPE_CHAR:
2125 case MONO_TYPE_R8: {
2128 /* boxed value type */
2129 t = g_new0 (MonoType, 1);
2131 klass = mono_class_from_mono_type (t);
2133 o = mono_object_new_checked (domain, klass, &error);
2134 if (!mono_error_ok (&error)) {
2135 mono_error_set_pending_exception (&error);
2138 v = ((gchar *) o) + sizeof (MonoObject);
2139 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2140 if (mono_error_set_pending_exception (&error))
2144 case MONO_TYPE_STRING:
2145 case MONO_TYPE_CLASS:
2146 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2147 if (mono_error_set_pending_exception (&error))
2151 g_assert_not_reached ();
2157 ICALL_EXPORT MonoReflectionType*
2158 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2161 MonoReflectionType *ret;
2164 type = mono_field_get_type_checked (ref_field->field, &error);
2165 if (!mono_error_ok (&error)) {
2166 mono_error_set_pending_exception (&error);
2170 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2171 if (!mono_error_ok (&error)) {
2172 mono_error_set_pending_exception (&error);
2179 /* From MonoProperty.cs */
2181 PInfo_Attributes = 1,
2182 PInfo_GetMethod = 1 << 1,
2183 PInfo_SetMethod = 1 << 2,
2184 PInfo_ReflectedType = 1 << 3,
2185 PInfo_DeclaringType = 1 << 4,
2190 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2193 MonoReflectionType *rt;
2194 MonoReflectionMethod *rm;
2195 MonoDomain *domain = mono_object_domain (property);
2196 const MonoProperty *pproperty = property->property;
2198 if ((req_info & PInfo_ReflectedType) != 0) {
2199 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2200 if (mono_error_set_pending_exception (&error))
2203 MONO_STRUCT_SETREF (info, parent, rt);
2205 if ((req_info & PInfo_DeclaringType) != 0) {
2206 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2207 if (mono_error_set_pending_exception (&error))
2210 MONO_STRUCT_SETREF (info, declaring_type, rt);
2213 if ((req_info & PInfo_Name) != 0)
2214 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2216 if ((req_info & PInfo_Attributes) != 0)
2217 info->attrs = pproperty->attrs;
2219 if ((req_info & PInfo_GetMethod) != 0) {
2220 if (pproperty->get &&
2221 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2222 pproperty->get->klass == property->klass)) {
2223 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2224 if (mono_error_set_pending_exception (&error))
2230 MONO_STRUCT_SETREF (info, get, rm);
2232 if ((req_info & PInfo_SetMethod) != 0) {
2233 if (pproperty->set &&
2234 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2235 pproperty->set->klass == property->klass)) {
2236 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2237 if (mono_error_set_pending_exception (&error))
2243 MONO_STRUCT_SETREF (info, set, rm);
2246 * There may be other methods defined for properties, though, it seems they are not exposed
2247 * in the reflection API
2252 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2255 MonoReflectionType *rt;
2256 MonoReflectionMethod *rm;
2257 MonoDomain *domain = mono_object_domain (event);
2259 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2260 if (mono_error_set_pending_exception (&error))
2263 MONO_STRUCT_SETREF (info, reflected_type, rt);
2265 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2266 if (mono_error_set_pending_exception (&error))
2269 MONO_STRUCT_SETREF (info, declaring_type, rt);
2271 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2272 info->attrs = event->event->attrs;
2274 if (event->event->add) {
2275 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2276 if (mono_error_set_pending_exception (&error))
2282 MONO_STRUCT_SETREF (info, add_method, rm);
2284 if (event->event->remove) {
2285 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2286 if (mono_error_set_pending_exception (&error))
2292 MONO_STRUCT_SETREF (info, remove_method, rm);
2294 if (event->event->raise) {
2295 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2296 if (mono_error_set_pending_exception (&error))
2302 MONO_STRUCT_SETREF (info, raise_method, rm);
2304 #ifndef MONO_SMALL_CONFIG
2305 if (event->event->other) {
2307 while (event->event->other [n])
2309 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2310 if (mono_error_set_pending_exception (&error))
2312 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2314 for (i = 0; i < n; i++) {
2315 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2316 if (mono_error_set_pending_exception (&error))
2318 mono_array_setref (info->other_methods, i, rm);
2325 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2330 mono_class_setup_interfaces (klass, error);
2331 if (!mono_error_ok (error))
2334 for (i = 0; i < klass->interface_count; i++) {
2335 ic = klass->interfaces [i];
2336 g_hash_table_insert (ifaces, ic, ic);
2338 collect_interfaces (ic, ifaces, error);
2339 if (!mono_error_ok (error))
2345 MonoArray *iface_array;
2346 MonoGenericContext *context;
2350 } FillIfaceArrayData;
2353 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2355 MonoReflectionType *rt;
2356 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2357 MonoClass *ic = (MonoClass *)key;
2358 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2360 if (!mono_error_ok (data->error))
2363 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2364 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2365 if (!mono_error_ok (data->error))
2369 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2370 if (!mono_error_ok (data->error))
2373 mono_array_setref (data->iface_array, data->next_idx++, rt);
2376 mono_metadata_free_type (inflated);
2380 get_interfaces_hash (gconstpointer v1)
2382 MonoClass *k = (MonoClass*)v1;
2384 return k->type_token;
2387 ICALL_EXPORT MonoArray*
2388 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2391 MonoClass *klass = mono_class_from_mono_type (type->type);
2393 FillIfaceArrayData data = { 0 };
2396 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2398 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2399 data.context = mono_class_get_context (klass);
2400 klass = mono_class_get_generic_class (klass)->container_class;
2403 for (parent = klass; parent; parent = parent->parent) {
2404 mono_class_setup_interfaces (parent, &error);
2405 if (!mono_error_ok (&error))
2407 collect_interfaces (parent, iface_hash, &error);
2408 if (!mono_error_ok (&error))
2412 data.error = &error;
2413 data.domain = mono_object_domain (type);
2415 len = g_hash_table_size (iface_hash);
2417 g_hash_table_destroy (iface_hash);
2418 if (!data.domain->empty_types) {
2419 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2420 if (!is_ok (&error))
2423 return data.domain->empty_types;
2426 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2427 if (!is_ok (&error))
2429 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2430 if (!mono_error_ok (&error))
2433 g_hash_table_destroy (iface_hash);
2434 return data.iface_array;
2437 g_hash_table_destroy (iface_hash);
2438 mono_error_set_pending_exception (&error);
2443 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2445 gboolean variance_used;
2446 MonoClass *klass = mono_class_from_mono_type (type->type);
2447 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2448 MonoReflectionMethod *member;
2451 int i = 0, len, ioffset;
2455 mono_class_init_checked (klass, &error);
2456 if (mono_error_set_pending_exception (&error))
2458 mono_class_init_checked (iclass, &error);
2459 if (mono_error_set_pending_exception (&error))
2462 mono_class_setup_vtable (klass);
2464 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2468 len = mono_class_num_methods (iclass);
2469 domain = mono_object_domain (type);
2470 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2471 if (mono_error_set_pending_exception (&error))
2473 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2474 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2475 if (mono_error_set_pending_exception (&error))
2477 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2479 while ((method = mono_class_get_methods (iclass, &iter))) {
2480 member = mono_method_get_object_checked (domain, method, iclass, &error);
2481 if (mono_error_set_pending_exception (&error))
2483 mono_array_setref (*methods, i, member);
2484 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2485 if (mono_error_set_pending_exception (&error))
2487 mono_array_setref (*targets, i, member);
2494 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2497 MonoClass *klass = mono_class_from_mono_type (type->type);
2499 mono_class_init_checked (klass, &error);
2500 if (mono_error_set_pending_exception (&error))
2503 if (image_is_dynamic (klass->image)) {
2504 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2505 *packing = tb->packing_size;
2506 *size = tb->class_size;
2508 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2512 ICALL_EXPORT MonoReflectionType*
2513 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2516 MonoReflectionType *ret;
2519 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2520 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2521 mono_error_set_pending_exception (&error);
2525 klass = mono_class_from_mono_type (type->type);
2526 mono_class_init_checked (klass, &error);
2527 if (mono_error_set_pending_exception (&error))
2531 // GetElementType should only return a type for:
2532 // Array Pointer PassedByRef
2533 if (type->type->byref)
2534 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2535 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2536 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2537 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2538 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2542 mono_error_set_pending_exception (&error);
2547 ICALL_EXPORT MonoReflectionType*
2548 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2551 MonoReflectionType *ret;
2553 if (type->type->byref)
2556 MonoClass *klass = mono_class_from_mono_type (type->type);
2560 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2561 mono_error_set_pending_exception (&error);
2566 ICALL_EXPORT MonoBoolean
2567 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2569 return type->type->type == MONO_TYPE_PTR;
2572 ICALL_EXPORT MonoBoolean
2573 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2575 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)));
2578 ICALL_EXPORT MonoBoolean
2579 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2581 return type->type->byref;
2584 ICALL_EXPORT MonoBoolean
2585 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2588 MonoClass *klass = mono_class_from_mono_type (type->type);
2589 mono_class_init_checked (klass, &error);
2590 if (mono_error_set_pending_exception (&error))
2593 return mono_class_is_com_object (klass);
2596 ICALL_EXPORT guint32
2597 ves_icall_reflection_get_token (MonoObject* obj)
2600 guint32 result = mono_reflection_get_token_checked (obj, &error);
2601 mono_error_set_pending_exception (&error);
2605 ICALL_EXPORT MonoReflectionModule*
2606 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2609 MonoReflectionModule *result = NULL;
2610 MonoClass *klass = mono_class_from_mono_type (type->type);
2611 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2612 mono_error_set_pending_exception (&error);
2616 ICALL_EXPORT MonoReflectionAssembly*
2617 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2620 MonoDomain *domain = mono_domain_get ();
2621 MonoClass *klass = mono_class_from_mono_type (type->type);
2622 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2623 mono_error_set_pending_exception (&error);
2627 ICALL_EXPORT MonoReflectionType*
2628 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2631 MonoReflectionType *ret;
2632 MonoDomain *domain = mono_domain_get ();
2635 if (type->type->byref)
2637 if (type->type->type == MONO_TYPE_VAR) {
2638 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2639 klass = param ? param->owner.klass : NULL;
2640 } else if (type->type->type == MONO_TYPE_MVAR) {
2641 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2642 klass = param ? param->owner.method->klass : NULL;
2644 klass = mono_class_from_mono_type (type->type)->nested_in;
2650 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2651 mono_error_set_pending_exception (&error);
2656 ICALL_EXPORT MonoStringHandle
2657 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2659 MonoDomain *domain = mono_domain_get ();
2660 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2661 MonoClass *klass = mono_class_from_mono_type (type);
2664 char *n = g_strdup_printf ("%s&", klass->name);
2665 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2671 return mono_string_new_handle (domain, klass->name, error);
2675 ICALL_EXPORT MonoStringHandle
2676 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2678 MonoDomain *domain = mono_domain_get ();
2679 MonoClass *klass = mono_class_from_mono_type_handle (type);
2681 while (klass->nested_in)
2682 klass = klass->nested_in;
2684 if (klass->name_space [0] == '\0')
2685 return NULL_HANDLE_STRING;
2687 return mono_string_new_handle (domain, klass->name_space, error);
2691 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2695 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2696 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2700 klass = mono_class_from_mono_type (type->type);
2706 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2708 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2711 ICALL_EXPORT MonoArray*
2712 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2715 MonoReflectionType *rt;
2717 MonoClass *klass, *pklass;
2718 MonoDomain *domain = mono_object_domain (type);
2721 klass = mono_class_from_mono_type (type->type);
2723 if (mono_class_is_gtd (klass)) {
2724 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2725 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2726 if (mono_error_set_pending_exception (&error))
2728 for (i = 0; i < container->type_argc; ++i) {
2729 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2731 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2732 if (mono_error_set_pending_exception (&error))
2735 mono_array_setref (res, i, rt);
2737 } else if (mono_class_is_ginst (klass)) {
2738 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2739 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2740 if (mono_error_set_pending_exception (&error))
2742 for (i = 0; i < inst->type_argc; ++i) {
2743 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2744 if (mono_error_set_pending_exception (&error))
2747 mono_array_setref (res, i, rt);
2755 ICALL_EXPORT gboolean
2756 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2760 if (!IS_MONOTYPE (type))
2763 if (type->type->byref)
2766 klass = mono_class_from_mono_type (type->type);
2767 return mono_class_is_gtd (klass);
2770 ICALL_EXPORT MonoReflectionType*
2771 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2774 MonoReflectionType *ret;
2777 if (type->type->byref)
2780 klass = mono_class_from_mono_type (type->type);
2782 if (mono_class_is_gtd (klass)) {
2783 return type; /* check this one */
2785 if (mono_class_is_ginst (klass)) {
2786 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2789 tb = mono_class_get_ref_info (generic_class);
2791 if (generic_class->wastypebuilder && tb)
2792 return (MonoReflectionType *)tb;
2794 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2795 mono_error_set_pending_exception (&error);
2803 ICALL_EXPORT MonoReflectionType*
2804 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2807 MonoReflectionType *ret;
2809 MonoType *geninst, **types;
2812 g_assert (IS_MONOTYPE (type));
2813 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2814 if (mono_error_set_pending_exception (&error))
2817 count = mono_array_length (type_array);
2818 types = g_new0 (MonoType *, count);
2820 for (i = 0; i < count; i++) {
2821 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2822 types [i] = t->type;
2825 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2828 mono_error_set_pending_exception (&error);
2832 klass = mono_class_from_mono_type (geninst);
2834 /*we might inflate to the GTD*/
2835 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2836 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2840 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2841 mono_error_set_pending_exception (&error);
2846 ICALL_EXPORT gboolean
2847 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2851 if (!IS_MONOTYPE (type))
2854 if (type->type->byref)
2857 klass = mono_class_from_mono_type (type->type);
2858 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2862 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2864 if (!IS_MONOTYPE (type))
2867 if (is_generic_parameter (type->type))
2868 return mono_type_get_generic_param_num (type->type);
2872 ICALL_EXPORT MonoGenericParamInfo *
2873 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2875 return mono_generic_param_info (type->type->data.generic_param);
2878 ICALL_EXPORT MonoBoolean
2879 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2881 return is_generic_parameter (type->type);
2884 ICALL_EXPORT MonoReflectionMethod*
2885 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2886 MonoReflectionMethod* generic)
2893 MonoReflectionMethod *ret = NULL;
2895 domain = ((MonoObject *)type)->vtable->domain;
2897 klass = mono_class_from_mono_type (type->type);
2898 mono_class_init_checked (klass, &error);
2899 if (mono_error_set_pending_exception (&error))
2903 while ((method = mono_class_get_methods (klass, &iter))) {
2904 if (method->token == generic->method->token) {
2905 ret = mono_method_get_object_checked (domain, method, klass, &error);
2906 if (mono_error_set_pending_exception (&error))
2914 ICALL_EXPORT MonoReflectionMethod *
2915 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2918 MonoType *type = ref_type->type;
2920 MonoReflectionMethod *ret = NULL;
2922 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2923 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2926 if (type->type == MONO_TYPE_VAR)
2929 method = mono_type_get_generic_param_owner (type)->owner.method;
2932 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2933 if (!mono_error_ok (&error))
2934 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2938 ICALL_EXPORT MonoBoolean
2939 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2941 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2945 ICALL_EXPORT MonoBoolean
2946 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2948 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2953 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2955 MonoDomain *domain = mono_domain_get ();
2956 MonoImage *image = method->method->klass->image;
2957 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2958 MonoTableInfo *tables = image->tables;
2959 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2960 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2961 guint32 im_cols [MONO_IMPLMAP_SIZE];
2962 guint32 scope_token;
2963 const char *import = NULL;
2964 const char *scope = NULL;
2966 if (image_is_dynamic (image)) {
2967 MonoReflectionMethodAux *method_aux =
2968 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2970 import = method_aux->dllentry;
2971 scope = method_aux->dll;
2974 if (!import || !scope) {
2975 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2980 if (piinfo->implmap_idx) {
2981 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2983 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2984 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2985 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2986 scope = mono_metadata_string_heap (image, scope_token);
2990 *flags = piinfo->piflags;
2991 *entry_point = mono_string_new (domain, import);
2992 *dll_name = mono_string_new (domain, scope);
2995 ICALL_EXPORT MonoReflectionMethod *
2996 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2998 MonoMethodInflated *imethod;
3000 MonoReflectionMethod *ret = NULL;
3003 if (method->method->is_generic)
3006 if (!method->method->is_inflated)
3009 imethod = (MonoMethodInflated *) method->method;
3011 result = imethod->declaring;
3012 /* Not a generic method. */
3013 if (!result->is_generic)
3016 if (image_is_dynamic (method->method->klass->image)) {
3017 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3018 MonoReflectionMethod *res;
3021 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3022 * the dynamic case as well ?
3024 mono_image_lock ((MonoImage*)image);
3025 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3026 mono_image_unlock ((MonoImage*)image);
3032 if (imethod->context.class_inst) {
3033 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3034 /*Generic methods gets the context of the GTD.*/
3035 if (mono_class_get_context (klass)) {
3036 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3037 if (!mono_error_ok (&error))
3042 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3044 if (!mono_error_ok (&error))
3045 mono_error_set_pending_exception (&error);
3049 ICALL_EXPORT gboolean
3050 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3052 return mono_method_signature (method->method)->generic_param_count != 0;
3055 ICALL_EXPORT gboolean
3056 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3058 return method->method->is_generic;
3061 ICALL_EXPORT MonoArray*
3062 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3065 MonoReflectionType *rt;
3070 domain = mono_object_domain (method);
3072 if (method->method->is_inflated) {
3073 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3076 count = inst->type_argc;
3077 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3078 if (mono_error_set_pending_exception (&error))
3081 for (i = 0; i < count; i++) {
3082 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3083 if (mono_error_set_pending_exception (&error))
3086 mono_array_setref (res, i, rt);
3093 count = mono_method_signature (method->method)->generic_param_count;
3094 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3095 if (mono_error_set_pending_exception (&error))
3098 for (i = 0; i < count; i++) {
3099 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3100 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3101 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3103 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3104 if (mono_error_set_pending_exception (&error))
3107 mono_array_setref (res, i, rt);
3113 ICALL_EXPORT MonoObject *
3114 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3118 * Invoke from reflection is supposed to always be a virtual call (the API
3119 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3120 * greater flexibility.
3122 MonoMethod *m = method->method;
3123 MonoMethodSignature *sig = mono_method_signature (m);
3126 void *obj = this_arg;
3130 if (mono_security_core_clr_enabled () &&
3131 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3132 mono_error_set_pending_exception (&error);
3136 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3137 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3138 mono_error_cleanup (&error); /* FIXME does this make sense? */
3139 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3144 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3145 if (!is_ok (&error)) {
3146 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3149 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3150 char *target_name = mono_type_get_full_name (m->klass);
3151 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3152 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3154 g_free (target_name);
3158 m = mono_object_get_virtual_method (this_arg, m);
3159 /* must pass the pointer to the value for valuetype methods */
3160 if (m->klass->valuetype)
3161 obj = mono_object_unbox (this_arg);
3162 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3163 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3168 if (sig->ret->byref) {
3169 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"));
3173 pcount = params? mono_array_length (params): 0;
3174 if (pcount != sig->param_count) {
3175 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3179 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3180 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."));
3184 image = m->klass->image;
3185 if (image->assembly->ref_only) {
3186 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."));
3190 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3191 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3195 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3199 intptr_t *lower_bounds;
3200 pcount = mono_array_length (params);
3201 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3202 /* Note: the synthetized array .ctors have int32 as argument type */
3203 for (i = 0; i < pcount; ++i)
3204 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3206 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3207 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3208 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3209 if (!mono_error_ok (&error)) {
3210 mono_error_set_pending_exception (&error);
3214 for (i = 0; i < mono_array_length (arr); ++i) {
3215 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3216 if (!mono_error_ok (&error)) {
3217 mono_error_set_pending_exception (&error);
3220 mono_array_setref_fast (arr, i, subarray);
3222 return (MonoObject*)arr;
3225 if (m->klass->rank == pcount) {
3226 /* Only lengths provided. */
3227 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3228 if (!mono_error_ok (&error)) {
3229 mono_error_set_pending_exception (&error);
3233 return (MonoObject*)arr;
3235 g_assert (pcount == (m->klass->rank * 2));
3236 /* The arguments are lower-bound-length pairs */
3237 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3239 for (i = 0; i < pcount / 2; ++i) {
3240 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3241 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3244 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3245 if (!mono_error_ok (&error)) {
3246 mono_error_set_pending_exception (&error);
3250 return (MonoObject*)arr;
3253 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3254 mono_error_set_pending_exception (&error);
3258 #ifndef DISABLE_REMOTING
3259 ICALL_EXPORT MonoObject *
3260 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3263 MonoDomain *domain = mono_object_domain (method);
3264 MonoMethod *m = method->method;
3265 MonoMethodSignature *sig = mono_method_signature (m);
3266 MonoArray *out_args;
3268 int i, j, outarg_count = 0;
3270 if (m->klass == mono_defaults.object_class) {
3271 if (!strcmp (m->name, "FieldGetter")) {
3272 MonoClass *k = this_arg->vtable->klass;
3276 /* If this is a proxy, then it must be a CBO */
3277 if (k == mono_defaults.transparent_proxy_class) {
3278 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3279 this_arg = tp->rp->unwrapped_server;
3280 g_assert (this_arg);
3281 k = this_arg->vtable->klass;
3284 name = mono_array_get (params, MonoString *, 1);
3285 str = mono_string_to_utf8_checked (name, &error);
3286 if (mono_error_set_pending_exception (&error))
3290 MonoClassField* field = mono_class_get_field_from_name (k, str);
3293 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3294 if (field_klass->valuetype) {
3295 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3296 if (mono_error_set_pending_exception (&error))
3299 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3301 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3302 if (mono_error_set_pending_exception (&error))
3304 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3305 mono_array_setref (out_args, 0, result);
3312 g_assert_not_reached ();
3314 } else if (!strcmp (m->name, "FieldSetter")) {
3315 MonoClass *k = this_arg->vtable->klass;
3321 /* If this is a proxy, then it must be a CBO */
3322 if (k == mono_defaults.transparent_proxy_class) {
3323 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3324 this_arg = tp->rp->unwrapped_server;
3325 g_assert (this_arg);
3326 k = this_arg->vtable->klass;
3329 name = mono_array_get (params, MonoString *, 1);
3330 str = mono_string_to_utf8_checked (name, &error);
3331 if (mono_error_set_pending_exception (&error))
3335 MonoClassField* field = mono_class_get_field_from_name (k, str);
3338 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3339 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3341 if (field_klass->valuetype) {
3342 size = mono_type_size (field->type, &align);
3343 g_assert (size == mono_class_value_size (field_klass, NULL));
3344 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3346 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3349 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3350 if (mono_error_set_pending_exception (&error))
3352 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3361 g_assert_not_reached ();
3366 for (i = 0; i < mono_array_length (params); i++) {
3367 if (sig->params [i]->byref)
3371 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3372 if (mono_error_set_pending_exception (&error))
3375 /* handle constructors only for objects already allocated */
3376 if (!strcmp (method->method->name, ".ctor"))
3377 g_assert (this_arg);
3379 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3380 g_assert (!method->method->klass->valuetype);
3381 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3382 if (mono_error_set_pending_exception (&error))
3385 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3386 if (sig->params [i]->byref) {
3388 arg = mono_array_get (params, gpointer, i);
3389 mono_array_setref (out_args, j, arg);
3394 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3401 read_enum_value (const char *mem, int type)
3404 case MONO_TYPE_BOOLEAN:
3406 return *(guint8*)mem;
3408 return *(gint8*)mem;
3409 case MONO_TYPE_CHAR:
3411 return read16 (mem);
3413 return (gint16) read16 (mem);
3415 return read32 (mem);
3417 return (gint32) read32 (mem);
3420 return read64 (mem);
3422 g_assert_not_reached ();
3428 write_enum_value (char *mem, int type, guint64 value)
3432 case MONO_TYPE_I1: {
3433 guint8 *p = (guint8*)mem;
3439 case MONO_TYPE_CHAR: {
3440 guint16 *p = (guint16 *)mem;
3445 case MONO_TYPE_I4: {
3446 guint32 *p = (guint32 *)mem;
3451 case MONO_TYPE_I8: {
3452 guint64 *p = (guint64 *)mem;
3457 g_assert_not_reached ();
3462 ICALL_EXPORT MonoObject *
3463 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3471 domain = mono_object_domain (enumType);
3472 enumc = mono_class_from_mono_type (enumType->type);
3474 mono_class_init_checked (enumc, &error);
3475 if (mono_error_set_pending_exception (&error))
3478 etype = mono_class_enum_basetype (enumc);
3480 res = mono_object_new_checked (domain, enumc, &error);
3481 if (mono_error_set_pending_exception (&error))
3483 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3488 ICALL_EXPORT MonoBoolean
3489 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3491 int size = mono_class_value_size (a->vtable->klass, NULL);
3492 guint64 a_val = 0, b_val = 0;
3494 memcpy (&a_val, mono_object_unbox (a), size);
3495 memcpy (&b_val, mono_object_unbox (b), size);
3497 return (a_val & b_val) == b_val;
3500 ICALL_EXPORT MonoObject *
3501 ves_icall_System_Enum_get_value (MonoObject *eobj)
3513 g_assert (eobj->vtable->klass->enumtype);
3515 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3516 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3517 if (mono_error_set_pending_exception (&error))
3519 dst = (char *)res + sizeof (MonoObject);
3520 src = (char *)eobj + sizeof (MonoObject);
3521 size = mono_class_value_size (enumc, NULL);
3523 memcpy (dst, src, size);
3528 ICALL_EXPORT MonoReflectionType *
3529 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3532 MonoReflectionType *ret;
3536 klass = mono_class_from_mono_type (type->type);
3537 mono_class_init_checked (klass, &error);
3538 if (mono_error_set_pending_exception (&error))
3541 etype = mono_class_enum_basetype (klass);
3543 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3547 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3548 mono_error_set_pending_exception (&error);
3554 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3556 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3557 gpointer odata = (char *)other + sizeof (MonoObject);
3558 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3559 g_assert (basetype);
3564 if (eobj->vtable->klass != other->vtable->klass)
3567 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3568 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3569 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3572 return me > other ? 1 : -1; \
3575 switch (basetype->type) {
3577 COMPARE_ENUM_VALUES (guint8);
3579 COMPARE_ENUM_VALUES (gint8);
3580 case MONO_TYPE_CHAR:
3582 COMPARE_ENUM_VALUES (guint16);
3584 COMPARE_ENUM_VALUES (gint16);
3586 COMPARE_ENUM_VALUES (guint32);
3588 COMPARE_ENUM_VALUES (gint32);
3590 COMPARE_ENUM_VALUES (guint64);
3592 COMPARE_ENUM_VALUES (gint64);
3596 #undef COMPARE_ENUM_VALUES
3597 /* indicates that the enum was of an unsupported unerlying type */
3602 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3604 gpointer data = (char *)eobj + sizeof (MonoObject);
3605 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3606 g_assert (basetype);
3608 switch (basetype->type) {
3609 case MONO_TYPE_I1: {
3610 gint8 value = *((gint8*)data);
3611 return ((int)value ^ (int)value << 8);
3614 return *((guint8*)data);
3615 case MONO_TYPE_CHAR:
3617 return *((guint16*)data);
3619 case MONO_TYPE_I2: {
3620 gint16 value = *((gint16*)data);
3621 return ((int)(guint16)value | (((int)value) << 16));
3624 return *((guint32*)data);
3626 return *((gint32*)data);
3628 case MONO_TYPE_I8: {
3629 gint64 value = *((gint64*)data);
3630 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3633 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3639 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3641 mono_error_init (error);
3642 HANDLE_FUNCTION_ENTER();
3643 guint64 field_value;
3645 MonoTypeEnum def_type;
3647 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3649 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3651 if (mono_field_is_deleted (field))
3653 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3656 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3658 p = mono_class_get_field_default_value (field, &def_type);
3659 /* len = */ mono_metadata_decode_blob_size (p, &p);
3661 field_value = read_enum_value (p, base_type);
3662 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3664 if (*previous_value > field_value)
3667 *previous_value = field_value;
3670 HANDLE_FUNCTION_RETURN();
3673 ICALL_EXPORT MonoBoolean
3674 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3676 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3677 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3678 guint j = 0, nvalues;
3680 MonoClassField *field;
3682 guint64 previous_value = 0;
3683 gboolean sorted = TRUE;
3685 mono_error_init (error);
3686 mono_class_init_checked (enumc, error);
3687 return_val_if_nok (error, FALSE);
3689 if (!enumc->enumtype) {
3690 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3694 base_type = mono_class_enum_basetype (enumc)->type;
3696 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3697 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3698 return_val_if_nok (error, FALSE);
3699 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3700 return_val_if_nok (error, FALSE);
3703 while ((field = mono_class_get_fields (enumc, &iter))) {
3704 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3708 return_val_if_nok (error, FALSE);
3714 BFLAGS_IgnoreCase = 1,
3715 BFLAGS_DeclaredOnly = 2,
3716 BFLAGS_Instance = 4,
3718 BFLAGS_Public = 0x10,
3719 BFLAGS_NonPublic = 0x20,
3720 BFLAGS_FlattenHierarchy = 0x40,
3721 BFLAGS_InvokeMethod = 0x100,
3722 BFLAGS_CreateInstance = 0x200,
3723 BFLAGS_GetField = 0x400,
3724 BFLAGS_SetField = 0x800,
3725 BFLAGS_GetProperty = 0x1000,
3726 BFLAGS_SetProperty = 0x2000,
3727 BFLAGS_ExactBinding = 0x10000,
3728 BFLAGS_SuppressChangeType = 0x20000,
3729 BFLAGS_OptionalParamBinding = 0x40000
3732 ICALL_EXPORT GPtrArray*
3733 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3736 MonoClass *startklass, *klass;
3739 int (*compare_func) (const char *s1, const char *s2) = NULL;
3740 MonoClassField *field;
3742 if (type->type->byref) {
3743 return g_ptr_array_new ();
3746 mono_error_init (&error);
3748 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3750 klass = startklass = mono_class_from_mono_type (type->type);
3752 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3755 if (mono_class_has_failure (klass)) {
3756 mono_error_set_for_class_failure (&error, klass);
3761 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3762 guint32 flags = mono_field_get_flags (field);
3764 if (mono_field_is_deleted_with_flags (field, flags))
3766 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3767 if (bflags & BFLAGS_Public)
3769 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3770 if (bflags & BFLAGS_NonPublic) {
3777 if (flags & FIELD_ATTRIBUTE_STATIC) {
3778 if (bflags & BFLAGS_Static)
3779 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3782 if (bflags & BFLAGS_Instance)
3789 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3792 g_ptr_array_add (ptr_array, field);
3794 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3800 g_ptr_array_free (ptr_array, TRUE);
3801 mono_error_set_pending_exception (&error);
3806 method_nonpublic (MonoMethod* method, gboolean start_klass)
3808 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3809 case METHOD_ATTRIBUTE_ASSEM:
3810 return (start_klass || mono_defaults.generic_ilist_class);
3811 case METHOD_ATTRIBUTE_PRIVATE:
3813 case METHOD_ATTRIBUTE_PUBLIC:
3821 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3824 MonoClass *startklass;
3828 /*FIXME, use MonoBitSet*/
3829 guint32 method_slots_default [8];
3830 guint32 *method_slots = NULL;
3831 int (*compare_func) (const char *s1, const char *s2) = NULL;
3833 array = g_ptr_array_new ();
3835 mono_error_init (error);
3838 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3840 /* An optimization for calls made from Delegate:CreateDelegate () */
3841 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3842 method = mono_get_delegate_invoke (klass);
3845 g_ptr_array_add (array, method);
3849 mono_class_setup_methods (klass);
3850 mono_class_setup_vtable (klass);
3851 if (mono_class_has_failure (klass))
3854 if (is_generic_parameter (&klass->byval_arg))
3855 nslots = mono_class_get_vtable_size (klass->parent);
3857 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3858 if (nslots >= sizeof (method_slots_default) * 8) {
3859 method_slots = g_new0 (guint32, nslots / 32 + 1);
3861 method_slots = method_slots_default;
3862 memset (method_slots, 0, sizeof (method_slots_default));
3865 mono_class_setup_methods (klass);
3866 mono_class_setup_vtable (klass);
3867 if (mono_class_has_failure (klass))
3871 while ((method = mono_class_get_methods (klass, &iter))) {
3873 if (method->slot != -1) {
3874 g_assert (method->slot < nslots);
3875 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3877 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3878 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3881 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3883 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3884 if (bflags & BFLAGS_Public)
3886 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3892 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3893 if (bflags & BFLAGS_Static)
3894 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3897 if (bflags & BFLAGS_Instance)
3905 if (compare_func (name, method->name))
3910 g_ptr_array_add (array, method);
3912 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3914 if (method_slots != method_slots_default)
3915 g_free (method_slots);
3920 if (method_slots != method_slots_default)
3921 g_free (method_slots);
3922 g_ptr_array_free (array, TRUE);
3924 g_assert (mono_class_has_failure (klass));
3925 mono_error_set_for_class_failure (error, klass);
3929 ICALL_EXPORT GPtrArray*
3930 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3933 GPtrArray *method_array;
3936 klass = mono_class_from_mono_type (type->type);
3937 if (type->type->byref) {
3938 return g_ptr_array_new ();
3941 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3942 mono_error_set_pending_exception (&error);
3943 return method_array;
3946 ICALL_EXPORT GPtrArray*
3947 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3949 MonoClass *startklass, *klass;
3952 gpointer iter = NULL;
3953 GPtrArray *res_array;
3956 if (type->type->byref) {
3957 return g_ptr_array_new ();
3960 klass = startklass = mono_class_from_mono_type (type->type);
3962 mono_class_setup_methods (klass);
3963 if (mono_class_has_failure (klass)) {
3964 mono_error_init (&error);
3965 mono_error_set_for_class_failure (&error, klass);
3966 mono_error_set_pending_exception (&error);
3970 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3973 while ((method = mono_class_get_methods (klass, &iter))) {
3975 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3977 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3978 if (bflags & BFLAGS_Public)
3981 if (bflags & BFLAGS_NonPublic)
3987 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3988 if (bflags & BFLAGS_Static)
3989 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3992 if (bflags & BFLAGS_Instance)
3998 g_ptr_array_add (res_array, method);
4005 property_hash (gconstpointer data)
4007 MonoProperty *prop = (MonoProperty*)data;
4009 return g_str_hash (prop->name);
4013 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4015 if (method1->slot != -1 && method1->slot == method2->slot)
4018 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4019 if (method1->is_inflated)
4020 method1 = ((MonoMethodInflated*) method1)->declaring;
4021 if (method2->is_inflated)
4022 method2 = ((MonoMethodInflated*) method2)->declaring;
4025 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4029 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4031 // Properties are hide-by-name-and-signature
4032 if (!g_str_equal (prop1->name, prop2->name))
4035 /* If we see a property in a generic method, we want to
4036 compare the generic signatures, not the inflated signatures
4037 because we might conflate two properties that were
4041 public T this[T t] { getter { return t; } } // method 1
4042 public U this[U u] { getter { return u; } } // method 2
4045 If we see int Foo<int,int>::Item[int] we need to know if
4046 the indexer came from method 1 or from method 2, and we
4047 shouldn't conflate them. (Bugzilla 36283)
4049 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4052 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4059 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4064 return method_nonpublic (accessor, start_klass);
4067 ICALL_EXPORT GPtrArray*
4068 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4071 MonoClass *startklass, *klass;
4076 int (*compare_func) (const char *s1, const char *s2) = NULL;
4078 GHashTable *properties = NULL;
4079 GPtrArray *res_array;
4081 if (type->type->byref) {
4082 return g_ptr_array_new ();
4085 mono_error_init (&error);
4087 klass = startklass = mono_class_from_mono_type (type->type);
4089 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4091 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4093 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4095 mono_class_setup_methods (klass);
4096 mono_class_setup_vtable (klass);
4097 if (mono_class_has_failure (klass)) {
4098 mono_error_set_for_class_failure (&error, klass);
4103 while ((prop = mono_class_get_properties (klass, &iter))) {
4109 flags = method->flags;
4112 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4113 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4114 if (bflags & BFLAGS_Public)
4116 } else if (bflags & BFLAGS_NonPublic) {
4117 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4118 property_accessor_nonpublic(prop->set, startklass == klass)) {
4125 if (flags & METHOD_ATTRIBUTE_STATIC) {
4126 if (bflags & BFLAGS_Static)
4127 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4130 if (bflags & BFLAGS_Instance)
4138 if (propname != NULL && compare_func (propname, prop->name))
4141 if (g_hash_table_lookup (properties, prop))
4144 g_ptr_array_add (res_array, prop);
4146 g_hash_table_insert (properties, prop, prop);
4148 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4151 g_hash_table_destroy (properties);
4158 g_hash_table_destroy (properties);
4159 g_ptr_array_free (res_array, TRUE);
4161 mono_error_set_pending_exception (&error);
4167 event_hash (gconstpointer data)
4169 MonoEvent *event = (MonoEvent*)data;
4171 return g_str_hash (event->name);
4175 event_equal (MonoEvent *event1, MonoEvent *event2)
4177 // Events are hide-by-name
4178 return g_str_equal (event1->name, event2->name);
4181 ICALL_EXPORT GPtrArray*
4182 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4185 MonoClass *startklass, *klass;
4190 int (*compare_func) (const char *s1, const char *s2) = NULL;
4191 GHashTable *events = NULL;
4192 GPtrArray *res_array;
4194 if (type->type->byref) {
4195 return g_ptr_array_new ();
4198 mono_error_init (&error);
4200 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4202 res_array = g_ptr_array_sized_new (4);
4204 klass = startklass = mono_class_from_mono_type (type->type);
4206 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4208 mono_class_setup_methods (klass);
4209 mono_class_setup_vtable (klass);
4210 if (mono_class_has_failure (klass)) {
4211 mono_error_set_for_class_failure (&error, klass);
4216 while ((event = mono_class_get_events (klass, &iter))) {
4218 method = event->add;
4220 method = event->remove;
4222 method = event->raise;
4224 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4225 if (bflags & BFLAGS_Public)
4227 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4228 if (bflags & BFLAGS_NonPublic)
4233 if (bflags & BFLAGS_NonPublic)
4239 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4240 if (bflags & BFLAGS_Static)
4241 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4244 if (bflags & BFLAGS_Instance)
4249 if (bflags & BFLAGS_Instance)
4254 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4257 if (g_hash_table_lookup (events, event))
4260 g_ptr_array_add (res_array, event);
4262 g_hash_table_insert (events, event, event);
4264 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4267 g_hash_table_destroy (events);
4273 g_hash_table_destroy (events);
4275 g_ptr_array_free (res_array, TRUE);
4277 mono_error_set_pending_exception (&error);
4281 ICALL_EXPORT GPtrArray *
4282 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4288 GPtrArray *res_array;
4290 if (type->type->byref) {
4291 return g_ptr_array_new ();
4294 klass = mono_class_from_mono_type (type->type);
4297 * If a nested type is generic, return its generic type definition.
4298 * Note that this means that the return value is essentially the set
4299 * of nested types of the generic type definition of @klass.
4301 * A note in MSDN claims that a generic type definition can have
4302 * nested types that aren't generic. In any case, the container of that
4303 * nested type would be the generic type definition.
4305 if (mono_class_is_ginst (klass))
4306 klass = mono_class_get_generic_class (klass)->container_class;
4308 res_array = g_ptr_array_new ();
4311 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4313 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4314 if (bflags & BFLAGS_Public)
4317 if (bflags & BFLAGS_NonPublic)
4323 if (str != NULL && strcmp (nested->name, str))
4326 g_ptr_array_add (res_array, &nested->byval_arg);
4332 ICALL_EXPORT MonoReflectionType*
4333 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4336 MonoReflectionType *ret;
4338 MonoType *type = NULL;
4339 MonoTypeNameParse info;
4340 gboolean type_resolve;
4342 /* On MS.NET, this does not fire a TypeResolve event */
4343 type_resolve = TRUE;
4344 str = mono_string_to_utf8_checked (name, &error);
4345 if (mono_error_set_pending_exception (&error))
4347 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4348 if (!mono_reflection_parse_type (str, &info)) {
4350 mono_reflection_free_type_info (&info);
4352 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4355 /*g_print ("failed parse\n");*/
4359 if (info.assembly.name) {
4361 mono_reflection_free_type_info (&info);
4363 /* 1.0 and 2.0 throw different exceptions */
4364 if (mono_defaults.generic_ilist_class)
4365 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4367 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4373 if (module != NULL) {
4374 if (module->image) {
4375 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4376 if (!is_ok (&error)) {
4378 mono_reflection_free_type_info (&info);
4379 mono_error_set_pending_exception (&error);
4386 if (assembly_is_dynamic (assembly->assembly)) {
4387 /* Enumerate all modules */
4388 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4392 if (abuilder->modules) {
4393 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4394 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4395 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4396 if (!is_ok (&error)) {
4398 mono_reflection_free_type_info (&info);
4399 mono_error_set_pending_exception (&error);
4407 if (!type && abuilder->loaded_modules) {
4408 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4409 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4410 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4411 if (!is_ok (&error)) {
4413 mono_reflection_free_type_info (&info);
4414 mono_error_set_pending_exception (&error);
4423 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4424 if (!is_ok (&error)) {
4426 mono_reflection_free_type_info (&info);
4427 mono_error_set_pending_exception (&error);
4432 mono_reflection_free_type_info (&info);
4434 MonoException *e = NULL;
4437 e = mono_get_exception_type_load (name, NULL);
4440 mono_set_pending_exception (e);
4444 if (type->type == MONO_TYPE_CLASS) {
4445 MonoClass *klass = mono_type_get_class (type);
4447 /* need to report exceptions ? */
4448 if (throwOnError && mono_class_has_failure (klass)) {
4449 /* report SecurityException (or others) that occured when loading the assembly */
4450 mono_error_set_for_class_failure (&error, klass);
4451 mono_error_set_pending_exception (&error);
4456 /* g_print ("got it\n"); */
4457 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4458 mono_error_set_pending_exception (&error);
4464 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4467 gchar *shadow_ini_file;
4470 /* Check for shadow-copied assembly */
4471 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4472 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4474 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4475 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4481 g_free (shadow_ini_file);
4482 if (content != NULL) {
4485 *filename = content;
4492 ICALL_EXPORT MonoString *
4493 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4495 MonoDomain *domain = mono_object_domain (assembly);
4496 MonoAssembly *mass = assembly->assembly;
4497 MonoString *res = NULL;
4502 if (g_path_is_absolute (mass->image->name)) {
4503 absolute = g_strdup (mass->image->name);
4504 dirname = g_path_get_dirname (absolute);
4506 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4507 dirname = g_strdup (mass->basedir);
4510 replace_shadow_path (domain, dirname, &absolute);
4513 mono_icall_make_platform_path (absolute);
4516 uri = g_filename_to_uri (absolute, NULL, NULL);
4518 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4519 uri = g_strconcat (prepend, absolute, NULL);
4523 res = mono_string_new (domain, uri);
4530 ICALL_EXPORT MonoBoolean
4531 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4533 MonoAssembly *mass = assembly->assembly;
4535 return mass->in_gac;
4538 ICALL_EXPORT MonoReflectionAssembly*
4539 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4544 MonoImageOpenStatus status;
4545 MonoReflectionAssembly* result = NULL;
4547 name = mono_string_to_utf8_checked (mname, &error);
4548 if (mono_error_set_pending_exception (&error))
4550 res = mono_assembly_load_with_partial_name (name, &status);
4556 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4558 mono_error_set_pending_exception (&error);
4562 ICALL_EXPORT MonoStringHandle
4563 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4565 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4566 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4567 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4570 ICALL_EXPORT MonoBoolean
4571 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4573 return assembly->assembly->ref_only;
4576 ICALL_EXPORT MonoStringHandle
4577 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4579 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4580 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4582 return mono_string_new_handle (domain, assembly->image->version, error);
4585 ICALL_EXPORT MonoReflectionMethod*
4586 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4589 MonoReflectionMethod *res = NULL;
4592 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4596 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4597 if (!mono_error_ok (&error))
4600 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4603 if (!mono_error_ok (&error))
4604 mono_error_set_pending_exception (&error);
4608 ICALL_EXPORT MonoReflectionModule*
4609 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4612 MonoReflectionModule *result = NULL;
4613 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4614 if (!mono_error_ok (&error))
4615 mono_error_set_pending_exception (&error);
4619 ICALL_EXPORT MonoArray*
4620 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4623 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4624 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4625 if (mono_error_set_pending_exception (&error))
4630 for (i = 0; i < table->rows; ++i) {
4631 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4632 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4637 ICALL_EXPORT MonoStringHandle
4638 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4641 guint8 aotid_sum = 0;
4642 MonoDomain* domain = mono_domain_get ();
4644 if (!domain->entry_assembly || !domain->entry_assembly->image)
4647 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4649 for (i = 0; i < 16; ++i)
4650 aotid_sum |= (*aotid)[i];
4655 gchar *guid = mono_guid_to_string((guint8*) aotid);
4656 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4661 static MonoAssemblyName*
4662 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4664 mono_error_init (error);
4665 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4667 mono_assembly_get_assemblyref (image, i, aname);
4668 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4669 /* name and culture are pointers into the image tables, but we need
4670 * real malloc'd strings (so that we can g_free() them later from
4671 * Mono.RuntimeMarshal.FreeAssemblyName) */
4672 aname->name = g_strdup (aname->name);
4673 aname->culture = g_strdup (aname->culture);
4674 /* Don't need the hash value in managed */
4675 aname->hash_value = NULL;
4676 aname->hash_len = 0;
4677 g_assert (aname->public_key == NULL);
4679 /* note: this function doesn't return the codebase on purpose (i.e. it can
4680 be used under partial trust as path information isn't present). */
4684 ICALL_EXPORT GPtrArray*
4685 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4687 mono_error_init (error);
4688 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4689 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4690 MonoImage *image = ass->image;
4692 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4693 int count = t->rows;
4695 GPtrArray *result = g_ptr_array_sized_new (count);
4697 for (int i = 0; i < count; i++) {
4698 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4701 g_ptr_array_add (result, aname);
4706 /* move this in some file in mono/util/ */
4708 g_concat_dir_and_file (const char *dir, const char *file)
4710 g_return_val_if_fail (dir != NULL, NULL);
4711 g_return_val_if_fail (file != NULL, NULL);
4714 * If the directory name doesn't have a / on the end, we need
4715 * to add one so we get a proper path to the file
4717 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4718 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4720 return g_strconcat (dir, file, NULL);
4724 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4727 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4729 guint32 cols [MONO_MANIFEST_SIZE];
4730 guint32 impl, file_idx;
4734 char *n = mono_string_to_utf8_checked (name, &error);
4735 if (mono_error_set_pending_exception (&error))
4738 for (i = 0; i < table->rows; ++i) {
4739 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4740 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4741 if (strcmp (val, n) == 0)
4745 if (i == table->rows)
4748 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4751 * this code should only be called after obtaining the
4752 * ResourceInfo and handling the other cases.
4754 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4755 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4757 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4758 if (mono_error_set_pending_exception (&error) || !module)
4762 module = assembly->assembly->image;
4765 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4766 if (mono_error_set_pending_exception (&error))
4768 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4770 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4773 ICALL_EXPORT gboolean
4774 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4777 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4779 guint32 cols [MONO_MANIFEST_SIZE];
4780 guint32 file_cols [MONO_FILE_SIZE];
4784 n = mono_string_to_utf8_checked (name, &error);
4785 if (mono_error_set_pending_exception (&error))
4787 for (i = 0; i < table->rows; ++i) {
4788 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4789 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4790 if (strcmp (val, n) == 0)
4794 if (i == table->rows)
4797 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4798 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4801 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4802 case MONO_IMPLEMENTATION_FILE:
4803 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4804 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4805 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4806 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4807 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4808 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4811 info->location = RESOURCE_LOCATION_EMBEDDED;
4814 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4815 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4816 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4817 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4818 mono_error_set_assembly_load (&error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4819 mono_error_set_pending_exception (&error);
4822 MonoReflectionAssembly *assm_obj;
4823 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4825 mono_error_set_pending_exception (&error);
4828 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4830 /* Obtain info recursively */
4831 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4832 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4835 case MONO_IMPLEMENTATION_EXP_TYPE:
4836 g_assert_not_reached ();
4844 ICALL_EXPORT MonoObject*
4845 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4848 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4849 MonoArray *result = NULL;
4854 /* check hash if needed */
4856 n = mono_string_to_utf8_checked (name, &error);
4857 if (mono_error_set_pending_exception (&error))
4860 for (i = 0; i < table->rows; ++i) {
4861 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4862 if (strcmp (val, n) == 0) {
4865 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4866 fn = mono_string_new (mono_object_domain (assembly), n);
4868 return (MonoObject*)fn;
4876 for (i = 0; i < table->rows; ++i) {
4877 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4881 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4882 if (mono_error_set_pending_exception (&error))
4887 for (i = 0; i < table->rows; ++i) {
4888 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4889 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4890 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4891 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4896 return (MonoObject*)result;
4899 ICALL_EXPORT MonoArray*
4900 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4903 MonoDomain *domain = mono_domain_get();
4906 int i, j, file_count = 0;
4907 MonoImage **modules;
4908 guint32 module_count, real_module_count;
4909 MonoTableInfo *table;
4910 guint32 cols [MONO_FILE_SIZE];
4911 MonoImage *image = assembly->assembly->image;
4913 g_assert (image != NULL);
4914 g_assert (!assembly_is_dynamic (assembly->assembly));
4916 table = &image->tables [MONO_TABLE_FILE];
4917 file_count = table->rows;
4919 modules = image->modules;
4920 module_count = image->module_count;
4922 real_module_count = 0;
4923 for (i = 0; i < module_count; ++i)
4925 real_module_count ++;
4927 klass = mono_class_get_module_class ();
4928 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
4929 if (mono_error_set_pending_exception (&error))
4932 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
4933 if (mono_error_set_pending_exception (&error))
4936 mono_array_setref (res, 0, image_obj);
4938 for (i = 0; i < module_count; ++i)
4940 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
4941 if (mono_error_set_pending_exception (&error))
4943 mono_array_setref (res, j, rm);
4947 for (i = 0; i < file_count; ++i, ++j) {
4948 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4949 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4950 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
4951 if (mono_error_set_pending_exception (&error))
4953 mono_array_setref (res, j, rm);
4956 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
4957 if (mono_error_set_pending_exception (&error))
4960 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4961 mono_error_set_assembly_load (&error, g_strdup (filename), "%s", "");
4962 mono_error_set_pending_exception (&error);
4965 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
4966 if (mono_error_set_pending_exception (&error))
4968 mono_array_setref (res, j, rm);
4975 ICALL_EXPORT MonoReflectionMethod*
4976 ves_icall_GetCurrentMethod (void)
4978 MonoReflectionMethod *res = NULL;
4981 MonoMethod *m = mono_method_get_last_managed ();
4984 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
4988 while (m->is_inflated)
4989 m = ((MonoMethodInflated*)m)->declaring;
4991 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
4992 mono_error_set_pending_exception (&error);
4998 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5001 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5004 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5005 //method is inflated, we should inflate it on the other class
5006 MonoGenericContext ctx;
5007 ctx.method_inst = inflated->context.method_inst;
5008 ctx.class_inst = inflated->context.class_inst;
5009 if (mono_class_is_ginst (klass))
5010 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5011 else if (mono_class_is_gtd (klass))
5012 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5013 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5014 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5018 mono_class_setup_methods (method->klass);
5019 if (mono_class_has_failure (method->klass))
5021 int mcount = mono_class_get_method_count (method->klass);
5022 for (i = 0; i < mcount; ++i) {
5023 if (method->klass->methods [i] == method) {
5028 mono_class_setup_methods (klass);
5029 if (mono_class_has_failure (klass))
5031 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5032 return klass->methods [offset];
5035 ICALL_EXPORT MonoReflectionMethod*
5036 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5038 MonoReflectionMethod *res = NULL;
5041 if (type && generic_check) {
5042 klass = mono_class_from_mono_type (type);
5043 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5046 if (method->klass != klass) {
5047 method = mono_method_get_equivalent_method (method, klass);
5052 klass = mono_class_from_mono_type (type);
5054 klass = method->klass;
5055 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5056 mono_error_set_pending_exception (&error);
5060 ICALL_EXPORT MonoReflectionMethodBody*
5061 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5064 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5065 mono_error_set_pending_exception (&error);
5069 ICALL_EXPORT MonoReflectionAssembly*
5070 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5073 MonoReflectionAssembly *result;
5074 MonoMethod *dest = NULL;
5076 mono_stack_walk_no_il (get_executing, &dest);
5078 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5080 mono_error_set_pending_exception (&error);
5085 ICALL_EXPORT MonoReflectionAssembly*
5086 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5089 MonoReflectionAssembly *result;
5090 MonoDomain* domain = mono_domain_get ();
5092 if (!domain->entry_assembly)
5095 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5097 mono_error_set_pending_exception (&error);
5101 ICALL_EXPORT MonoReflectionAssembly*
5102 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5107 MonoReflectionAssembly *result;
5110 mono_stack_walk_no_il (get_executing, &dest);
5112 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5116 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5119 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5121 mono_error_set_pending_exception (&error);
5125 ICALL_EXPORT MonoStringHandle
5126 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5127 gboolean assembly_qualified, MonoError *error)
5129 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5130 MonoType *type = MONO_HANDLE_RAW (object)->type;
5131 MonoTypeNameFormat format;
5132 MonoStringHandle res;
5136 format = assembly_qualified ?
5137 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5138 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5140 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5142 name = mono_type_get_name_full (type, format);
5144 return NULL_HANDLE_STRING;
5146 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5148 return NULL_HANDLE_STRING;
5151 res = mono_string_new_handle (domain, name, error);
5158 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5161 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5163 mono_class_init_checked (klass, &error);
5164 mono_error_set_pending_exception (&error);
5165 return mono_security_core_clr_class_level (klass);
5169 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5171 MonoClassField *field = rfield->field;
5172 return mono_security_core_clr_field_level (field, TRUE);
5176 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5178 MonoMethod *method = rfield->method;
5179 return mono_security_core_clr_method_level (method, TRUE);
5182 ICALL_EXPORT MonoString *
5183 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5185 MonoDomain *domain = mono_object_domain (assembly);
5186 MonoAssembly *mass = assembly->assembly;
5190 name = mono_stringify_assembly_name (&mass->aname);
5191 res = mono_string_new (domain, name);
5197 ICALL_EXPORT MonoAssemblyName *
5198 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5200 return &mass->aname;
5204 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5207 MonoImageOpenStatus status = MONO_IMAGE_OK;
5208 char *codebase = NULL;
5213 mono_error_init (error);
5215 filename = mono_string_handle_to_utf8 (fname, error);
5216 return_if_nok (error);
5218 dirname = g_path_get_dirname (filename);
5219 replace_shadow_path (mono_domain_get (), dirname, &filename);
5222 image = mono_image_open (filename, &status);
5225 if (status == MONO_IMAGE_IMAGE_INVALID)
5226 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5228 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5233 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5235 mono_image_close (image);
5237 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5241 if (filename != NULL && *filename != '\0') {
5244 codebase = g_strdup (filename);
5246 mono_icall_make_platform_path (codebase);
5248 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5250 result = g_strconcat (prepend, codebase, NULL);
5254 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5257 mono_image_close (image);
5261 ICALL_EXPORT MonoBoolean
5262 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5263 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5265 MonoBoolean result = FALSE;
5266 MonoDeclSecurityEntry entry;
5268 /* SecurityAction.RequestMinimum */
5269 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5270 *minimum = entry.blob;
5271 *minLength = entry.size;
5274 /* SecurityAction.RequestOptional */
5275 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5276 *optional = entry.blob;
5277 *optLength = entry.size;
5280 /* SecurityAction.RequestRefuse */
5281 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5282 *refused = entry.blob;
5283 *refLength = entry.size;
5291 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5293 guint32 attrs, visibility;
5295 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5296 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5297 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5300 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5306 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5308 mono_error_init (error);
5309 HANDLE_FUNCTION_ENTER ();
5310 MonoError klass_error;
5311 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5314 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5315 return_if_nok (error);
5317 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5319 MonoException *ex = mono_error_convert_to_exception (error);
5320 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5322 HANDLE_FUNCTION_RETURN ();
5325 static MonoArrayHandle
5326 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5328 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5331 mono_error_init (error);
5333 /* we start the count from 1 because we skip the special type <Module> */
5336 for (i = 1; i < tdef->rows; ++i) {
5337 if (mono_module_type_is_visible (tdef, image, i + 1))
5341 count = tdef->rows - 1;
5343 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5344 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5345 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5346 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5348 for (i = 1; i < tdef->rows; ++i) {
5349 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5350 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5351 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5360 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5362 HANDLE_FUNCTION_ENTER ();
5363 mono_error_init (error);
5364 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5365 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5369 /* Append the new types to the end of the array */
5370 if (mono_array_handle_length (res2) > 0) {
5373 len1 = mono_array_handle_length (res);
5374 len2 = mono_array_handle_length (res2);
5376 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5380 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5381 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5382 MONO_HANDLE_ASSIGN (res, res3);
5384 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5388 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5389 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5390 MONO_HANDLE_ASSIGN (exceptions, ex3);
5393 HANDLE_FUNCTION_RETURN ();
5397 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5399 HANDLE_FUNCTION_ENTER ();
5400 MonoError unboxed_error;
5401 mono_error_init (&unboxed_error);
5402 mono_error_set_for_class_failure (&unboxed_error, klass);
5404 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5405 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5406 HANDLE_FUNCTION_RETURN ();
5409 ICALL_EXPORT MonoArrayHandle
5410 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5412 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5415 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5416 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5418 g_assert (!assembly_is_dynamic (assembly));
5419 MonoImage *image = assembly->image;
5420 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5421 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5422 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5424 /* Append data from all modules in the assembly */
5425 for (i = 0; i < table->rows; ++i) {
5426 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5427 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5428 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5431 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5432 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5437 /* the ReflectionTypeLoadException must have all the types (Types property),
5438 * NULL replacing types which throws an exception. The LoaderException must
5439 * contain all exceptions for NULL items.
5442 int len = mono_array_handle_length (res);
5446 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5447 for (i = 0; i < len; i++) {
5448 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5450 if (!MONO_HANDLE_IS_NULL (t)) {
5451 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5452 if ((klass != NULL) && mono_class_has_failure (klass)) {
5453 /* keep the class in the list */
5454 list = g_list_append (list, klass);
5455 /* and replace Type with NULL */
5456 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5463 if (list || ex_count) {
5465 int j, length = g_list_length (list) + ex_count;
5467 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5468 if (!is_ok (error)) {
5470 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5472 /* Types for which mono_class_get_checked () succeeded */
5473 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5474 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5475 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5477 /* Types for which it don't */
5478 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5479 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5480 if (!MONO_HANDLE_IS_NULL (exc)) {
5481 g_assert (i < length);
5482 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5489 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5490 if (!is_ok (error)) {
5491 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5493 mono_error_set_exception_handle (error, exc);
5494 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5501 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5503 mono_assembly_name_free (aname);
5508 ICALL_EXPORT gboolean
5509 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5511 *is_version_definited = *is_token_defined = FALSE;
5513 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5516 ICALL_EXPORT MonoReflectionTypeHandle
5517 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5519 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5520 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5525 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5527 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5528 /* These images do not have a global type */
5531 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5535 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5541 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5543 /*if (module->image)
5544 mono_image_close (module->image);*/
5547 ICALL_EXPORT MonoStringHandle
5548 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5550 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5551 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5554 return mono_string_new_handle (domain, image->guid, error);
5558 static inline gpointer
5559 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5561 return (gpointer) (-1);
5563 #endif /* HOST_WIN32 */
5565 ICALL_EXPORT gpointer
5566 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5568 return mono_icall_module_get_hinstance (module);
5572 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5574 if (image_is_dynamic (image)) {
5575 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5576 *pe_kind = dyn->pe_kind;
5577 *machine = dyn->machine;
5580 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5581 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5586 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5588 return (image->md_version_major << 16) | (image->md_version_minor);
5591 ICALL_EXPORT MonoArrayHandle
5592 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5594 mono_error_init (error);
5596 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5597 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5600 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5603 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5604 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5605 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5607 int n = mono_array_handle_length (exceptions);
5608 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5609 for (int i = 0; i < n; ++i) {
5610 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5611 if (!MONO_HANDLE_IS_NULL (ex)) {
5612 mono_error_set_exception_handle (error, ex);
5613 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5621 mono_memberref_is_method (MonoImage *image, guint32 token)
5623 if (!image_is_dynamic (image)) {
5624 guint32 cols [MONO_MEMBERREF_SIZE];
5626 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5627 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5628 mono_metadata_decode_blob_size (sig, &sig);
5629 return (*sig != 0x6);
5632 MonoClass *handle_class;
5634 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5635 mono_error_cleanup (&error); /* just probing, ignore error */
5639 return mono_defaults.methodhandle_class == handle_class;
5644 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5647 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5648 mono_array_addr (type_args, MonoType*, 0));
5650 context->class_inst = NULL;
5652 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5653 mono_array_addr (method_args, MonoType*, 0));
5655 context->method_inst = NULL;
5658 ICALL_EXPORT MonoType*
5659 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5662 int table = mono_metadata_token_table (token);
5663 int index = mono_metadata_token_index (token);
5664 MonoGenericContext context;
5667 *resolve_error = ResolveTokenError_Other;
5669 /* Validate token */
5670 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5671 (table != MONO_TABLE_TYPESPEC)) {
5672 *resolve_error = ResolveTokenError_BadTable;
5676 if (image_is_dynamic (image)) {
5677 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5678 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5679 mono_error_cleanup (&error);
5680 return klass ? &klass->byval_arg : NULL;
5683 init_generic_context_from_args (&context, type_args, method_args);
5684 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5685 mono_error_cleanup (&error);
5686 return klass ? &klass->byval_arg : NULL;
5689 if ((index <= 0) || (index > image->tables [table].rows)) {
5690 *resolve_error = ResolveTokenError_OutOfRange;
5694 init_generic_context_from_args (&context, type_args, method_args);
5695 klass = mono_class_get_checked (image, token, &error);
5697 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5698 if (!mono_error_ok (&error)) {
5699 mono_error_set_pending_exception (&error);
5704 return &klass->byval_arg;
5709 ICALL_EXPORT MonoMethod*
5710 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5713 int table = mono_metadata_token_table (token);
5714 int index = mono_metadata_token_index (token);
5715 MonoGenericContext context;
5718 *resolve_error = ResolveTokenError_Other;
5720 /* Validate token */
5721 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5722 (table != MONO_TABLE_MEMBERREF)) {
5723 *resolve_error = ResolveTokenError_BadTable;
5727 if (image_is_dynamic (image)) {
5728 if (table == MONO_TABLE_METHOD) {
5729 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5730 mono_error_cleanup (&error);
5734 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5735 *resolve_error = ResolveTokenError_BadTable;
5739 init_generic_context_from_args (&context, type_args, method_args);
5740 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5741 mono_error_cleanup (&error);
5745 if ((index <= 0) || (index > image->tables [table].rows)) {
5746 *resolve_error = ResolveTokenError_OutOfRange;
5749 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5750 *resolve_error = ResolveTokenError_BadTable;
5754 init_generic_context_from_args (&context, type_args, method_args);
5755 method = mono_get_method_checked (image, token, NULL, &context, &error);
5756 mono_error_set_pending_exception (&error);
5761 ICALL_EXPORT MonoString*
5762 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5765 int index = mono_metadata_token_index (token);
5767 *resolve_error = ResolveTokenError_Other;
5769 /* Validate token */
5770 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5771 *resolve_error = ResolveTokenError_BadTable;
5775 if (image_is_dynamic (image)) {
5776 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5777 mono_error_cleanup (&error);
5781 if ((index <= 0) || (index >= image->heap_us.size)) {
5782 *resolve_error = ResolveTokenError_OutOfRange;
5786 /* FIXME: What to do if the index points into the middle of a string ? */
5788 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5789 mono_error_set_pending_exception (&error);
5793 ICALL_EXPORT MonoClassField*
5794 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5798 int table = mono_metadata_token_table (token);
5799 int index = mono_metadata_token_index (token);
5800 MonoGenericContext context;
5801 MonoClassField *field;
5803 *resolve_error = ResolveTokenError_Other;
5805 /* Validate token */
5806 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5807 *resolve_error = ResolveTokenError_BadTable;
5811 if (image_is_dynamic (image)) {
5812 if (table == MONO_TABLE_FIELD) {
5813 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5814 mono_error_cleanup (&error);
5818 if (mono_memberref_is_method (image, token)) {
5819 *resolve_error = ResolveTokenError_BadTable;
5823 init_generic_context_from_args (&context, type_args, method_args);
5824 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5825 mono_error_cleanup (&error);
5829 if ((index <= 0) || (index > image->tables [table].rows)) {
5830 *resolve_error = ResolveTokenError_OutOfRange;
5833 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5834 *resolve_error = ResolveTokenError_BadTable;
5838 init_generic_context_from_args (&context, type_args, method_args);
5839 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5840 mono_error_set_pending_exception (&error);
5846 ICALL_EXPORT MonoObject*
5847 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5851 int table = mono_metadata_token_table (token);
5853 *error = ResolveTokenError_Other;
5856 case MONO_TABLE_TYPEDEF:
5857 case MONO_TABLE_TYPEREF:
5858 case MONO_TABLE_TYPESPEC: {
5859 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5861 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5862 mono_error_set_pending_exception (&merror);
5869 case MONO_TABLE_METHOD:
5870 case MONO_TABLE_METHODSPEC: {
5871 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5873 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5874 mono_error_set_pending_exception (&merror);
5880 case MONO_TABLE_FIELD: {
5881 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5883 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5884 mono_error_set_pending_exception (&merror);
5890 case MONO_TABLE_MEMBERREF:
5891 if (mono_memberref_is_method (image, token)) {
5892 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5894 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5895 mono_error_set_pending_exception (&merror);
5902 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5904 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5905 mono_error_set_pending_exception (&merror);
5914 *error = ResolveTokenError_BadTable;
5920 ICALL_EXPORT MonoArray*
5921 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5924 int table = mono_metadata_token_table (token);
5925 int idx = mono_metadata_token_index (token);
5926 MonoTableInfo *tables = image->tables;
5931 *resolve_error = ResolveTokenError_OutOfRange;
5933 /* FIXME: Support other tables ? */
5934 if (table != MONO_TABLE_STANDALONESIG)
5937 if (image_is_dynamic (image))
5940 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5943 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5945 ptr = mono_metadata_blob_heap (image, sig);
5946 len = mono_metadata_decode_blob_size (ptr, &ptr);
5948 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
5949 if (mono_error_set_pending_exception (&error))
5951 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5955 ICALL_EXPORT MonoBoolean
5956 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
5962 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5968 check_for_invalid_type (MonoClass *klass, MonoError *error)
5972 mono_error_init (error);
5974 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
5977 name = mono_type_get_full_name (klass);
5978 mono_error_set_type_load_name (error, name, g_strdup (""), "");
5980 ICALL_EXPORT MonoReflectionType *
5981 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
5984 MonoReflectionType *ret;
5985 MonoClass *klass, *aklass;
5987 klass = mono_class_from_mono_type (type->type);
5988 check_for_invalid_type (klass, &error);
5989 if (mono_error_set_pending_exception (&error))
5992 if (rank == 0) //single dimentional array
5993 aklass = mono_array_class_get (klass, 1);
5995 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
5997 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
5998 mono_error_set_pending_exception (&error);
6003 ICALL_EXPORT MonoReflectionType *
6004 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6007 MonoReflectionType *ret;
6010 klass = mono_class_from_mono_type (type->type);
6011 mono_class_init_checked (klass, &error);
6012 if (mono_error_set_pending_exception (&error))
6015 check_for_invalid_type (klass, &error);
6016 if (mono_error_set_pending_exception (&error))
6019 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6020 mono_error_set_pending_exception (&error);
6025 ICALL_EXPORT MonoReflectionType *
6026 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6029 MonoReflectionType *ret;
6030 MonoClass *klass, *pklass;
6032 klass = mono_class_from_mono_type (type->type);
6033 mono_class_init_checked (klass, &error);
6034 if (mono_error_set_pending_exception (&error))
6036 check_for_invalid_type (klass, &error);
6037 if (mono_error_set_pending_exception (&error))
6040 pklass = mono_ptr_class_get (type->type);
6042 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6043 mono_error_set_pending_exception (&error);
6048 ICALL_EXPORT MonoObject *
6049 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6050 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6053 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6054 MonoObject *delegate;
6056 MonoMethod *method = info->method;
6057 MonoMethodSignature *sig = mono_method_signature(method);
6059 mono_class_init_checked (delegate_class, &error);
6060 if (mono_error_set_pending_exception (&error))
6063 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6064 /* FIXME improve this exception message */
6065 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6067 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6068 mono_error_set_pending_exception (&error);
6072 if (mono_security_core_clr_enabled ()) {
6073 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6074 if (throwOnBindFailure)
6075 mono_error_set_pending_exception (&error);
6077 mono_error_cleanup (&error);
6082 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6083 if (!method->is_inflated) {
6084 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"));
6089 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6090 if (mono_error_set_pending_exception (&error))
6093 if (method_is_dynamic (method)) {
6094 /* Creating a trampoline would leak memory */
6095 func = mono_compile_method_checked (method, &error);
6096 if (mono_error_set_pending_exception (&error))
6099 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6100 method = mono_object_get_virtual_method (target, method);
6101 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6102 if (mono_error_set_pending_exception (&error))
6104 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6107 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6108 if (mono_error_set_pending_exception (&error))
6113 ICALL_EXPORT MonoMulticastDelegate *
6114 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6117 MonoMulticastDelegate *ret;
6119 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6121 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6122 if (mono_error_set_pending_exception (&error))
6125 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6130 ICALL_EXPORT MonoReflectionMethod*
6131 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6133 MonoReflectionMethod *ret = NULL;
6135 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6136 mono_error_set_pending_exception (&error);
6142 static inline gint32
6143 mono_array_get_byte_length (MonoArray *array)
6149 klass = array->obj.vtable->klass;
6151 if (array->bounds == NULL)
6152 length = array->max_length;
6155 for (i = 0; i < klass->rank; ++ i)
6156 length *= array->bounds [i].length;
6159 switch (klass->element_class->byval_arg.type) {
6162 case MONO_TYPE_BOOLEAN:
6166 case MONO_TYPE_CHAR:
6174 return length * sizeof (gpointer);
6185 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6187 return mono_array_get_byte_length (array);
6191 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6193 return mono_array_get (array, gint8, idx);
6197 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6199 mono_array_set (array, gint8, idx, value);
6202 ICALL_EXPORT MonoBoolean
6203 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6205 guint8 *src_buf, *dest_buf;
6208 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6212 g_assert (count >= 0);
6214 /* This is called directly from the class libraries without going through the managed wrapper */
6215 MONO_CHECK_ARG_NULL (src, FALSE);
6216 MONO_CHECK_ARG_NULL (dest, FALSE);
6218 /* watch out for integer overflow */
6219 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6222 src_buf = (guint8 *)src->vector + src_offset;
6223 dest_buf = (guint8 *)dest->vector + dest_offset;
6226 memcpy (dest_buf, src_buf, count);
6228 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6233 #ifndef DISABLE_REMOTING
6234 ICALL_EXPORT MonoObject *
6235 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6238 MonoDomain *domain = mono_object_domain (this_obj);
6240 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6241 MonoTransparentProxy *tp;
6245 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6246 if (mono_error_set_pending_exception (&error))
6249 tp = (MonoTransparentProxy*) res;
6251 MONO_OBJECT_SETREF (tp, rp, rp);
6252 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6253 klass = mono_class_from_mono_type (type);
6255 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6256 mono_class_setup_vtable (klass);
6257 if (mono_class_has_failure (klass)) {
6258 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6262 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6263 if (mono_error_set_pending_exception (&error))
6265 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6266 if (mono_error_set_pending_exception (&error))
6269 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6270 if (mono_error_set_pending_exception (&error))
6275 ICALL_EXPORT MonoReflectionType *
6276 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6279 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6280 mono_error_set_pending_exception (&error);
6286 /* System.Environment */
6289 ves_icall_System_Environment_get_UserName (void)
6291 /* using glib is more portable */
6292 return mono_string_new (mono_domain_get (), g_get_user_name ());
6297 mono_icall_get_machine_name (void)
6299 #if !defined(DISABLE_SOCKETS)
6303 #if defined _SC_HOST_NAME_MAX
6304 n = sysconf (_SC_HOST_NAME_MAX);
6308 buf = g_malloc (n+1);
6310 if (gethostname (buf, n) == 0){
6312 result = mono_string_new (mono_domain_get (), buf);
6319 return mono_string_new (mono_domain_get (), "mono");
6322 #endif /* !HOST_WIN32 */
6324 ICALL_EXPORT MonoString *
6325 ves_icall_System_Environment_get_MachineName (void)
6327 return mono_icall_get_machine_name ();
6332 mono_icall_get_platform (void)
6334 #if defined(__MACH__)
6337 // Notice that the value is hidden from user code, and only exposed
6338 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6339 // define and making assumptions based on Unix/128/4 values before there
6340 // was a MacOS define. Lots of code would assume that not-Unix meant
6341 // Windows, but in this case, it would be OSX.
6349 #endif /* !HOST_WIN32 */
6352 ves_icall_System_Environment_get_Platform (void)
6354 return mono_icall_get_platform ();
6358 static inline MonoString *
6359 mono_icall_get_new_line (void)
6361 return mono_string_new (mono_domain_get (), "\n");
6363 #endif /* !HOST_WIN32 */
6365 ICALL_EXPORT MonoString *
6366 ves_icall_System_Environment_get_NewLine (void)
6368 return mono_icall_get_new_line ();
6372 static inline MonoBoolean
6373 mono_icall_is_64bit_os (void)
6375 #if SIZEOF_VOID_P == 8
6378 #if defined(HAVE_SYS_UTSNAME_H)
6379 struct utsname name;
6381 if (uname (&name) >= 0) {
6382 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6388 #endif /* !HOST_WIN32 */
6390 ICALL_EXPORT MonoBoolean
6391 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6393 return mono_icall_is_64bit_os ();
6396 ICALL_EXPORT MonoStringHandle
6397 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6401 if (utf8_name == NULL)
6402 return NULL_HANDLE_STRING;
6404 value = g_getenv (utf8_name);
6407 return NULL_HANDLE_STRING;
6409 return mono_string_new_handle (mono_domain_get (), value, error);
6413 * There is no standard way to get at environ.
6416 #ifndef __MINGW32_VERSION
6417 #if defined(__APPLE__)
6418 #if defined (TARGET_OSX)
6419 /* Apple defines this in crt_externs.h but doesn't provide that header for
6420 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6421 * in fact exist on all implementations (so far)
6423 gchar ***_NSGetEnviron(void);
6424 #define environ (*_NSGetEnviron())
6426 static char *mono_environ[1] = { NULL };
6427 #define environ mono_environ
6428 #endif /* defined (TARGET_OSX) */
6436 ICALL_EXPORT MonoArray *
6437 ves_icall_System_Environment_GetCoomandLineArgs (void)
6440 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6441 mono_error_set_pending_exception (&error);
6447 mono_icall_get_environment_variable_names (void)
6457 for (e = environ; *e != 0; ++ e)
6460 domain = mono_domain_get ();
6461 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6462 if (mono_error_set_pending_exception (&error))
6466 for (e = environ; *e != 0; ++ e) {
6467 parts = g_strsplit (*e, "=", 2);
6469 str = mono_string_new (domain, *parts);
6470 mono_array_setref (names, n, str);
6480 #endif /* !HOST_WIN32 */
6482 ICALL_EXPORT MonoArray *
6483 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6485 return mono_icall_get_environment_variable_names ();
6490 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6492 gchar *utf8_name, *utf8_value;
6495 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6496 if (mono_error_set_pending_exception (&error))
6499 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6500 g_unsetenv (utf8_name);
6505 utf8_value = mono_string_to_utf8_checked (value, &error);
6506 if (!mono_error_ok (&error)) {
6508 mono_error_set_pending_exception (&error);
6511 g_setenv (utf8_name, utf8_value, TRUE);
6514 g_free (utf8_value);
6516 #endif /* !HOST_WIN32 */
6519 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6521 mono_icall_set_environment_variable (name, value);
6525 ves_icall_System_Environment_Exit (int result)
6527 mono_environment_exitcode_set (result);
6529 /* FIXME: There are some cleanup hangs that should be worked out, but
6530 * if the program is going to exit, everything will be cleaned up when
6531 * NaCl exits anyway.
6533 #ifndef __native_client__
6534 if (!mono_runtime_try_shutdown ())
6535 mono_thread_exit ();
6537 /* Suspend all managed threads since the runtime is going away */
6538 mono_thread_suspend_all_other_threads ();
6540 mono_runtime_quit ();
6543 /* we may need to do some cleanup here... */
6547 ICALL_EXPORT MonoStringHandle
6548 ves_icall_System_Environment_GetGacPath (MonoError *error)
6550 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6554 static inline MonoString *
6555 mono_icall_get_windows_folder_path (int folder)
6557 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6558 return mono_string_new (mono_domain_get (), "");
6560 #endif /* !HOST_WIN32 */
6562 ICALL_EXPORT MonoString*
6563 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6565 return mono_icall_get_windows_folder_path (folder);
6568 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6570 mono_icall_get_logical_drives (void)
6573 gunichar2 buf [256], *ptr, *dname;
6575 guint initial_size = 127, size = 128;
6578 MonoString *drivestr;
6579 MonoDomain *domain = mono_domain_get ();
6585 while (size > initial_size) {
6586 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6587 if (size > initial_size) {
6590 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6591 initial_size = size;
6605 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6606 if (mono_error_set_pending_exception (&error))
6613 while (*u16) { u16++; len ++; }
6614 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6615 if (mono_error_set_pending_exception (&error))
6618 mono_array_setref (result, ndrives++, drivestr);
6628 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6630 ICALL_EXPORT MonoArray *
6631 ves_icall_System_Environment_GetLogicalDrives (void)
6633 return mono_icall_get_logical_drives ();
6636 ICALL_EXPORT MonoString *
6637 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6640 gunichar2 volume_name [MAX_PATH + 1];
6642 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6644 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6645 mono_error_set_pending_exception (&error);
6649 ICALL_EXPORT MonoStringHandle
6650 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6652 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6655 static const char *encodings [] = {
6657 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6658 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6659 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6661 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6662 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6663 "x_unicode_2_0_utf_7",
6665 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6666 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6668 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6671 "unicodefffe", "utf_16be",
6678 * Returns the internal codepage, if the value of "int_code_page" is
6679 * 1 at entry, and we can not compute a suitable code page number,
6680 * returns the code page as a string
6682 ICALL_EXPORT MonoString*
6683 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6688 char *codepage = NULL;
6690 int want_name = *int_code_page;
6693 *int_code_page = -1;
6695 g_get_charset (&cset);
6696 c = codepage = g_strdup (cset);
6697 for (c = codepage; *c; c++){
6698 if (isascii (*c) && isalpha (*c))
6703 /* g_print ("charset: %s\n", cset); */
6705 /* handle some common aliases */
6708 for (i = 0; p != 0; ){
6711 p = encodings [++i];
6714 if (strcmp (p, codepage) == 0){
6715 *int_code_page = code;
6718 p = encodings [++i];
6721 if (strstr (codepage, "utf_8") != NULL)
6722 *int_code_page |= 0x10000000;
6725 if (want_name && *int_code_page == -1)
6726 return mono_string_new (mono_domain_get (), cset);
6731 ICALL_EXPORT MonoBoolean
6732 ves_icall_System_Environment_get_HasShutdownStarted (void)
6734 if (mono_runtime_is_shutting_down ())
6737 if (mono_domain_is_unloading (mono_domain_get ()))
6745 mono_icall_broadcast_setting_change (void)
6749 #endif /* !HOST_WIN32 */
6752 ves_icall_System_Environment_BroadcastSettingChange (void)
6754 mono_icall_broadcast_setting_change ();
6759 ves_icall_System_Environment_get_TickCount (void)
6761 /* this will overflow after ~24 days */
6762 return (gint32) (mono_msec_boottime () & 0xffffffff);
6766 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6771 #ifndef DISABLE_REMOTING
6772 ICALL_EXPORT MonoBoolean
6773 ves_icall_IsTransparentProxy (MonoObject *proxy)
6778 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6784 ICALL_EXPORT MonoReflectionMethod *
6785 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6786 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6788 MonoReflectionMethod *ret = NULL;
6793 MonoMethod **vtable;
6794 MonoMethod *res = NULL;
6796 MONO_CHECK_ARG_NULL (rtype, NULL);
6797 MONO_CHECK_ARG_NULL (rmethod, NULL);
6799 method = rmethod->method;
6800 klass = mono_class_from_mono_type (rtype->type);
6801 mono_class_init_checked (klass, &error);
6802 if (mono_error_set_pending_exception (&error))
6805 if (MONO_CLASS_IS_INTERFACE (klass))
6808 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6811 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6812 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6818 mono_class_setup_vtable (klass);
6819 vtable = klass->vtable;
6821 if (mono_class_is_interface (method->klass)) {
6822 gboolean variance_used = FALSE;
6823 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6824 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6826 res = vtable [offs + method->slot];
6828 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6831 if (method->slot != -1)
6832 res = vtable [method->slot];
6838 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6839 mono_error_set_pending_exception (&error);
6844 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6850 klass = mono_class_from_mono_type (type->type);
6851 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6852 if (!is_ok (&error)) {
6853 mono_error_set_pending_exception (&error);
6857 mono_vtable_set_is_remote (vtable, enable);
6860 #else /* DISABLE_REMOTING */
6863 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6865 g_assert_not_reached ();
6870 ICALL_EXPORT MonoObject *
6871 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6878 domain = mono_object_domain (type);
6879 klass = mono_class_from_mono_type (type->type);
6880 mono_class_init_checked (klass, &error);
6881 if (mono_error_set_pending_exception (&error))
6884 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6885 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6889 if (klass->rank >= 1) {
6890 g_assert (klass->rank == 1);
6891 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6892 mono_error_set_pending_exception (&error);
6895 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6896 if (!is_ok (&error)) {
6897 mono_error_set_pending_exception (&error);
6900 /* Bypass remoting object creation check */
6901 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6902 mono_error_set_pending_exception (&error);
6908 ICALL_EXPORT MonoStringHandle
6909 ves_icall_System_IO_get_temp_path (MonoError *error)
6911 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6914 #ifndef PLATFORM_NO_DRIVEINFO
6915 ICALL_EXPORT MonoBoolean
6916 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
6917 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
6921 ULARGE_INTEGER wapi_free_bytes_avail;
6922 ULARGE_INTEGER wapi_total_number_of_bytes;
6923 ULARGE_INTEGER wapi_total_number_of_free_bytes;
6925 *error = ERROR_SUCCESS;
6926 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
6927 &wapi_total_number_of_free_bytes);
6930 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
6931 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
6932 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
6934 *free_bytes_avail = 0;
6935 *total_number_of_bytes = 0;
6936 *total_number_of_free_bytes = 0;
6937 *error = GetLastError ();
6943 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6944 static inline guint32
6945 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
6947 return GetDriveType (mono_string_chars (root_path_name));
6949 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6951 ICALL_EXPORT guint32
6952 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
6954 return mono_icall_drive_info_get_drive_type (root_path_name);
6957 #endif /* PLATFORM_NO_DRIVEINFO */
6959 ICALL_EXPORT gpointer
6960 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
6963 gpointer result = mono_compile_method_checked (method, &error);
6964 mono_error_set_pending_exception (&error);
6968 ICALL_EXPORT MonoString *
6969 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6974 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6976 mono_icall_make_platform_path (path);
6978 mcpath = mono_string_new (mono_domain_get (), path);
6984 /* this is an icall */
6986 get_bundled_app_config (void)
6989 const gchar *app_config;
6992 gchar *config_file_name, *config_file_path;
6993 gsize len, config_file_path_length, config_ext_length;
6996 domain = mono_domain_get ();
6997 file = domain->setup->configuration_file;
6998 if (!file || file->length == 0)
7001 // Retrieve config file and remove the extension
7002 config_file_name = mono_string_to_utf8_checked (file, &error);
7003 if (mono_error_set_pending_exception (&error))
7005 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7006 if (!config_file_path)
7007 config_file_path = config_file_name;
7009 config_file_path_length = strlen (config_file_path);
7010 config_ext_length = strlen (".config");
7011 if (config_file_path_length <= config_ext_length)
7014 len = config_file_path_length - config_ext_length;
7015 module = (gchar *)g_malloc0 (len + 1);
7016 memcpy (module, config_file_path, len);
7017 // Get the config file from the module name
7018 app_config = mono_config_string_for_assembly_file (module);
7021 if (config_file_name != config_file_path)
7022 g_free (config_file_name);
7023 g_free (config_file_path);
7028 return mono_string_new (mono_domain_get (), app_config);
7031 static MonoStringHandle
7032 get_bundled_machine_config (MonoError *error)
7034 const gchar *machine_config;
7036 machine_config = mono_get_machine_config ();
7038 if (!machine_config)
7039 return NULL_HANDLE_STRING;
7041 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7044 ICALL_EXPORT MonoStringHandle
7045 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7047 return get_bundled_machine_config (error);
7051 ICALL_EXPORT MonoStringHandle
7052 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7054 return get_bundled_machine_config (error);
7057 ICALL_EXPORT MonoStringHandle
7058 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7060 return get_bundled_machine_config (error);
7064 ICALL_EXPORT MonoString *
7065 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7070 path = g_path_get_dirname (mono_get_config_dir ());
7072 mono_icall_make_platform_path (path);
7074 ipath = mono_string_new (mono_domain_get (), path);
7080 ICALL_EXPORT gboolean
7081 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7083 MonoPEResourceDataEntry *entry;
7086 if (!assembly || !result || !size)
7091 image = assembly->assembly->image;
7092 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7096 *result = mono_image_rva_map (image, entry->rde_data_offset);
7101 *size = entry->rde_size;
7106 ICALL_EXPORT MonoBoolean
7107 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7109 return mono_is_debugger_attached ();
7112 ICALL_EXPORT MonoBoolean
7113 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7115 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7116 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7122 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7124 if (mono_get_runtime_callbacks ()->debug_log)
7125 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7130 mono_icall_write_windows_debug_string (MonoString *message)
7132 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7134 #endif /* !HOST_WIN32 */
7137 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7139 mono_icall_write_windows_debug_string (message);
7142 /* Only used for value types */
7143 ICALL_EXPORT MonoObject *
7144 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7151 domain = mono_object_domain (type);
7152 klass = mono_class_from_mono_type (type->type);
7153 mono_class_init_checked (klass, &error);
7154 if (mono_error_set_pending_exception (&error))
7157 if (mono_class_is_nullable (klass))
7158 /* No arguments -> null */
7161 result = mono_object_new_checked (domain, klass, &error);
7162 mono_error_set_pending_exception (&error);
7166 ICALL_EXPORT MonoReflectionMethod *
7167 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7169 MonoReflectionMethod *ret = NULL;
7172 MonoClass *klass, *parent;
7173 MonoGenericContext *generic_inst = NULL;
7174 MonoMethod *method = m->method;
7175 MonoMethod *result = NULL;
7178 if (method->klass == NULL)
7181 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7182 MONO_CLASS_IS_INTERFACE (method->klass) ||
7183 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7186 slot = mono_method_get_vtable_slot (method);
7190 klass = method->klass;
7191 if (mono_class_is_ginst (klass)) {
7192 generic_inst = mono_class_get_context (klass);
7193 klass = mono_class_get_generic_class (klass)->container_class;
7198 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7199 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7200 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7201 or klass is the generic container class and generic_inst is the instantiation.
7203 when we go to the parent, if the parent is an open constructed type, we need to
7204 replace the type parameters by the definitions from the generic_inst, and then take it
7205 apart again into the klass and the generic_inst.
7207 For cases like this:
7208 class C<T> : B<T, int> {
7209 public override void Foo () { ... }
7211 class B<U,V> : A<HashMap<U,V>> {
7212 public override void Foo () { ... }
7215 public virtual void Foo () { ... }
7218 if at each iteration the parent isn't open, we can skip inflating it. if at some
7219 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7222 MonoGenericContext *parent_inst = NULL;
7223 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7224 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7225 if (!mono_error_ok (&error)) {
7226 mono_error_set_pending_exception (&error);
7230 if (mono_class_is_ginst (parent)) {
7231 parent_inst = mono_class_get_context (parent);
7232 parent = mono_class_get_generic_class (parent)->container_class;
7235 mono_class_setup_vtable (parent);
7236 if (parent->vtable_size <= slot)
7239 generic_inst = parent_inst;
7242 klass = klass->parent;
7245 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7246 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7247 if (!mono_error_ok (&error)) {
7248 mono_error_set_pending_exception (&error);
7252 generic_inst = NULL;
7254 if (mono_class_is_ginst (klass)) {
7255 generic_inst = mono_class_get_context (klass);
7256 klass = mono_class_get_generic_class (klass)->container_class;
7262 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7263 if (!mono_error_ok (&error)) {
7264 mono_error_set_pending_exception (&error);
7269 if (klass == method->klass)
7272 /*This is possible if definition == FALSE.
7273 * Do it here to be really sure we don't read invalid memory.
7275 if (slot >= klass->vtable_size)
7278 mono_class_setup_vtable (klass);
7280 result = klass->vtable [slot];
7281 if (result == NULL) {
7282 /* It is an abstract method */
7283 gboolean found = FALSE;
7284 gpointer iter = NULL;
7285 while ((result = mono_class_get_methods (klass, &iter))) {
7286 if (result->slot == slot) {
7291 /* found might be FALSE if we looked in an abstract class
7292 * that doesn't override an abstract method of its
7294 * abstract class Base {
7295 * public abstract void Foo ();
7297 * abstract class Derived : Base { }
7298 * class Child : Derived {
7299 * public override void Foo () { }
7302 * if m was Child.Foo and we ask for the base method,
7303 * then we get here with klass == Derived and found == FALSE
7305 /* but it shouldn't be the case that if we're looking
7306 * for the definition and didn't find a result; the
7307 * loop above should've taken us as far as we could
7309 g_assert (!(definition && !found));
7314 g_assert (result != NULL);
7316 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7317 mono_error_set_pending_exception (&error);
7321 ICALL_EXPORT MonoString*
7322 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7324 MonoMethod *method = m->method;
7326 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7331 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7333 iter->sig = *(MonoMethodSignature**)argsp;
7335 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7336 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7339 /* FIXME: it's not documented what start is exactly... */
7343 iter->args = argsp + sizeof (gpointer);
7345 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7347 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7350 ICALL_EXPORT MonoTypedRef
7351 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7353 guint32 i, arg_size;
7357 i = iter->sig->sentinelpos + iter->next_arg;
7359 g_assert (i < iter->sig->param_count);
7361 res.type = iter->sig->params [i];
7362 res.klass = mono_class_from_mono_type (res.type);
7363 arg_size = mono_type_stack_size (res.type, &align);
7364 #if defined(__arm__) || defined(__mips__)
7365 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7367 res.value = iter->args;
7368 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7369 /* Values are stored as 8 byte register sized objects, but 'value'
7370 * is dereferenced as a pointer in other routines.
7372 res.value = (char*)res.value + 4;
7374 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7375 if (arg_size <= sizeof (gpointer)) {
7377 int padding = arg_size - mono_type_size (res.type, &dummy);
7378 res.value = (guint8*)res.value + padding;
7381 iter->args = (char*)iter->args + arg_size;
7384 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7389 ICALL_EXPORT MonoTypedRef
7390 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7392 guint32 i, arg_size;
7396 i = iter->sig->sentinelpos + iter->next_arg;
7398 g_assert (i < iter->sig->param_count);
7400 while (i < iter->sig->param_count) {
7401 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7403 res.type = iter->sig->params [i];
7404 res.klass = mono_class_from_mono_type (res.type);
7405 /* FIXME: endianess issue... */
7406 arg_size = mono_type_stack_size (res.type, &align);
7407 #if defined(__arm__) || defined(__mips__)
7408 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7410 res.value = iter->args;
7411 iter->args = (char*)iter->args + arg_size;
7413 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7416 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7424 ICALL_EXPORT MonoType*
7425 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7429 i = iter->sig->sentinelpos + iter->next_arg;
7431 g_assert (i < iter->sig->param_count);
7433 return iter->sig->params [i];
7436 ICALL_EXPORT MonoObject*
7437 mono_TypedReference_ToObject (MonoTypedRef* tref)
7440 MonoObject *result = NULL;
7441 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7442 MonoObject** objp = (MonoObject **)tref->value;
7446 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7447 mono_error_set_pending_exception (&error);
7451 ICALL_EXPORT MonoTypedRef
7452 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7455 MonoReflectionField *f;
7457 MonoType *ftype = NULL;
7461 memset (&res, 0, sizeof (res));
7464 g_assert (mono_array_length (fields) > 0);
7466 klass = target->vtable->klass;
7468 for (i = 0; i < mono_array_length (fields); ++i) {
7469 f = mono_array_get (fields, MonoReflectionField*, i);
7471 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7474 if (f->field->parent != klass) {
7475 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7479 p = (guint8*)target + f->field->offset;
7481 p += f->field->offset - sizeof (MonoObject);
7482 klass = mono_class_from_mono_type (f->field->type);
7483 ftype = f->field->type;
7487 res.klass = mono_class_from_mono_type (ftype);
7494 prelink_method (MonoMethod *method, MonoError *error)
7496 const char *exc_class, *exc_arg;
7498 mono_error_init (error);
7499 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7501 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7503 mono_error_set_exception_instance (error,
7504 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7507 /* create the wrapper, too? */
7511 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7515 prelink_method (method->method, &error);
7516 mono_error_set_pending_exception (&error);
7520 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7523 MonoClass *klass = mono_class_from_mono_type (type->type);
7525 gpointer iter = NULL;
7527 mono_class_init_checked (klass, &error);
7528 if (mono_error_set_pending_exception (&error))
7531 while ((m = mono_class_get_methods (klass, &iter))) {
7532 prelink_method (m, &error);
7533 if (mono_error_set_pending_exception (&error))
7538 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7540 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7541 gint32 const **exponents,
7542 gunichar2 const **digitLowerTable,
7543 gunichar2 const **digitUpperTable,
7544 gint64 const **tenPowersList,
7545 gint32 const **decHexDigits)
7547 *mantissas = Formatter_MantissaBitsTable;
7548 *exponents = Formatter_TensExponentTable;
7549 *digitLowerTable = Formatter_DigitLowerTable;
7550 *digitUpperTable = Formatter_DigitUpperTable;
7551 *tenPowersList = Formatter_TenPowersList;
7552 *decHexDigits = Formatter_DecHexDigits;
7556 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7557 * and avoid useless allocations.
7560 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7562 MonoReflectionType *rt;
7566 mono_error_init (error);
7567 for (i = 0; i < type->num_mods; ++i) {
7568 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7573 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7574 return_val_if_nok (error, NULL);
7576 for (i = 0; i < type->num_mods; ++i) {
7577 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7578 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7579 return_val_if_nok (error, NULL);
7581 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7582 return_val_if_nok (error, NULL);
7584 mono_array_setref (res, count, rt);
7591 ICALL_EXPORT MonoArray*
7592 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7595 MonoType *type = param->ClassImpl->type;
7596 MonoClass *member_class = mono_object_class (param->MemberImpl);
7597 MonoMethod *method = NULL;
7600 MonoMethodSignature *sig;
7603 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7604 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7605 method = rmethod->method;
7606 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7607 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7608 if (!(method = prop->property->get))
7609 method = prop->property->set;
7612 char *type_name = mono_type_get_full_name (member_class);
7613 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7614 MonoException *ex = mono_get_exception_not_supported (msg);
7617 mono_set_pending_exception (ex);
7621 image = method->klass->image;
7622 pos = param->PositionImpl;
7623 sig = mono_method_signature (method);
7627 type = sig->params [pos];
7629 res = type_array_from_modifiers (image, type, optional, &error);
7630 mono_error_set_pending_exception (&error);
7635 get_property_type (MonoProperty *prop)
7637 MonoMethodSignature *sig;
7639 sig = mono_method_signature (prop->get);
7641 } else if (prop->set) {
7642 sig = mono_method_signature (prop->set);
7643 return sig->params [sig->param_count - 1];
7648 ICALL_EXPORT MonoArray*
7649 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7652 MonoType *type = get_property_type (property->property);
7653 MonoImage *image = property->klass->image;
7658 res = type_array_from_modifiers (image, type, optional, &error);
7659 mono_error_set_pending_exception (&error);
7664 *Construct a MonoType suited to be used to decode a constant blob object.
7666 * @type is the target type which will be constructed
7667 * @blob_type is the blob type, for example, that comes from the constant table
7668 * @real_type is the expected constructed type.
7671 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7673 type->type = blob_type;
7674 type->data.klass = NULL;
7675 if (blob_type == MONO_TYPE_CLASS)
7676 type->data.klass = mono_defaults.object_class;
7677 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7678 /* For enums, we need to use the base type */
7679 type->type = MONO_TYPE_VALUETYPE;
7680 type->data.klass = mono_class_from_mono_type (real_type);
7682 type->data.klass = mono_class_from_mono_type (real_type);
7685 ICALL_EXPORT MonoObject*
7686 property_info_get_default_value (MonoReflectionProperty *property)
7690 MonoProperty *prop = property->property;
7691 MonoType *type = get_property_type (prop);
7692 MonoDomain *domain = mono_object_domain (property);
7693 MonoTypeEnum def_type;
7694 const char *def_value;
7697 mono_class_init (prop->parent);
7699 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7700 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7704 def_value = mono_class_get_property_default_value (prop, &def_type);
7706 mono_type_from_blob_type (&blob_type, def_type, type);
7707 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7709 mono_error_set_pending_exception (&error);
7713 ICALL_EXPORT MonoBoolean
7714 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7717 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7718 MonoCustomAttrInfo *cinfo;
7721 mono_class_init_checked (attr_class, &error);
7722 if (mono_error_set_pending_exception (&error))
7725 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7726 if (!is_ok (&error)) {
7727 mono_error_set_pending_exception (&error);
7732 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7734 mono_custom_attrs_free (cinfo);
7738 ICALL_EXPORT MonoArray*
7739 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7741 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7746 mono_class_init_checked (attr_class, &error);
7747 if (mono_error_set_pending_exception (&error))
7751 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7752 if (!mono_error_ok (&error)) {
7753 mono_error_set_pending_exception (&error);
7760 ICALL_EXPORT MonoArray*
7761 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7765 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7766 mono_error_set_pending_exception (&error);
7771 ICALL_EXPORT MonoStringHandle
7772 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7775 MonoStringHandle display_name;
7777 mono_error_init (error);
7778 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7779 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7781 return display_name;
7784 ICALL_EXPORT MonoString*
7785 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7788 MonoString *message;
7792 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7793 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7796 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7798 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7799 if (mono_error_set_pending_exception (&error))
7807 static inline gint32
7808 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7810 return WAIT_TIMEOUT;
7812 #endif /* !HOST_WIN32 */
7815 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7817 return mono_icall_wait_for_input_idle (handle, milliseconds);
7821 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7823 return mono_process_current_pid ();
7826 ICALL_EXPORT MonoBoolean
7827 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7839 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7841 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7845 ICALL_EXPORT MonoObject*
7846 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7848 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7853 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7855 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7859 ICALL_EXPORT MonoObject*
7860 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7862 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7866 ICALL_EXPORT MonoBoolean
7867 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7869 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7874 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7876 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7880 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7882 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7887 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7889 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7893 ICALL_EXPORT mono_unichar2*
7894 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7896 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7903 #ifndef DISABLE_ICALL_TABLES
7905 #define ICALL_TYPE(id,name,first)
7906 #define ICALL(id,name,func) Icall_ ## id,
7907 #define HANDLES(inner) inner
7910 #include "metadata/icall-def.h"
7916 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7917 #define ICALL(id,name,func)
7919 #define HANDLES(inner) inner
7921 #include "metadata/icall-def.h"
7927 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7928 #define ICALL(id,name,func)
7930 #define HANDLES(inner) inner
7932 guint16 first_icall;
7935 static const IcallTypeDesc
7936 icall_type_descs [] = {
7937 #include "metadata/icall-def.h"
7941 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7944 #define HANDLES(inner) inner
7946 #define ICALL_TYPE(id,name,first)
7949 #ifdef HAVE_ARRAY_ELEM_INIT
7950 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7951 #define MSGSTRFIELD1(line) str##line
7953 static const struct msgstrtn_t {
7954 #define ICALL(id,name,func)
7956 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7957 #include "metadata/icall-def.h"
7959 } icall_type_names_str = {
7960 #define ICALL_TYPE(id,name,first) (name),
7961 #include "metadata/icall-def.h"
7964 static const guint16 icall_type_names_idx [] = {
7965 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7966 #include "metadata/icall-def.h"
7969 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7971 static const struct msgstr_t {
7973 #define ICALL_TYPE(id,name,first)
7974 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7975 #include "metadata/icall-def.h"
7977 } icall_names_str = {
7978 #define ICALL(id,name,func) (name),
7979 #include "metadata/icall-def.h"
7982 static const guint16 icall_names_idx [] = {
7983 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7984 #include "metadata/icall-def.h"
7987 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7993 #define ICALL_TYPE(id,name,first) name,
7994 #define ICALL(id,name,func)
7995 static const char* const
7996 icall_type_names [] = {
7997 #include "metadata/icall-def.h"
8001 #define icall_type_name_get(id) (icall_type_names [(id)])
8005 #define ICALL_TYPE(id,name,first)
8006 #define ICALL(id,name,func) name,
8007 static const char* const
8009 #include "metadata/icall-def.h"
8012 #define icall_name_get(id) icall_names [(id)]
8014 #endif /* !HAVE_ARRAY_ELEM_INIT */
8017 #define HANDLES(inner) inner
8020 #define ICALL_TYPE(id,name,first)
8021 #define ICALL(id,name,func) func,
8022 static const gconstpointer
8023 icall_functions [] = {
8024 #include "metadata/icall-def.h"
8028 #ifdef ENABLE_ICALL_SYMBOL_MAP
8030 #define HANDLES(inner) inner
8033 #define ICALL_TYPE(id,name,first)
8034 #define ICALL(id,name,func) #func,
8035 static const gconstpointer
8036 icall_symbols [] = {
8037 #include "metadata/icall-def.h"
8044 #define ICALL_TYPE(id,name,first)
8045 #define ICALL(id,name,func) 0,
8047 #define HANDLES(inner) 1,
8049 icall_uses_handles [] = {
8050 #include "metadata/icall-def.h"
8055 #endif /* DISABLE_ICALL_TABLES */
8057 static mono_mutex_t icall_mutex;
8058 static GHashTable *icall_hash = NULL;
8059 static GHashTable *jit_icall_hash_name = NULL;
8060 static GHashTable *jit_icall_hash_addr = NULL;
8063 mono_icall_init (void)
8065 #ifndef DISABLE_ICALL_TABLES
8068 /* check that tables are sorted: disable in release */
8071 const char *prev_class = NULL;
8072 const char *prev_method;
8074 for (i = 0; i < Icall_type_num; ++i) {
8075 const IcallTypeDesc *desc;
8078 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8079 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8080 prev_class = icall_type_name_get (i);
8081 desc = &icall_type_descs [i];
8082 num_icalls = icall_desc_num_icalls (desc);
8083 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8084 for (j = 0; j < num_icalls; ++j) {
8085 const char *methodn = icall_name_get (desc->first_icall + j);
8086 if (prev_method && strcmp (prev_method, methodn) >= 0)
8087 g_print ("method %s should come before method %s\n", methodn, prev_method);
8088 prev_method = methodn;
8094 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8095 mono_os_mutex_init (&icall_mutex);
8099 mono_icall_lock (void)
8101 mono_locks_os_acquire (&icall_mutex, IcallLock);
8105 mono_icall_unlock (void)
8107 mono_locks_os_release (&icall_mutex, IcallLock);
8111 mono_icall_cleanup (void)
8113 g_hash_table_destroy (icall_hash);
8114 g_hash_table_destroy (jit_icall_hash_name);
8115 g_hash_table_destroy (jit_icall_hash_addr);
8116 mono_os_mutex_destroy (&icall_mutex);
8120 * mono_add_internal_call:
8121 * @name: method specification to surface to the managed world
8122 * @method: pointer to a C method to invoke when the method is called
8124 * This method surfaces the C function pointed by @method as a method
8125 * that has been surfaced in managed code with the method specified in
8126 * @name as an internal call.
8128 * Internal calls are surfaced to all app domains loaded and they are
8129 * accessibly by a type with the specified name.
8131 * You must provide a fully qualified type name, that is namespaces
8132 * and type name, followed by a colon and the method name, with an
8133 * optional signature to bind.
8135 * For example, the following are all valid declarations:
8137 * "MyApp.Services.ScriptService:Accelerate"
8138 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8140 * You use method parameters in cases where there might be more than
8141 * one surface method to managed code. That way you can register different
8142 * internal calls for different method overloads.
8144 * The internal calls are invoked with no marshalling. This means that .NET
8145 * types like System.String are exposed as `MonoString *` parameters. This is
8146 * different than the way that strings are surfaced in P/Invoke.
8148 * For more information on how the parameters are marshalled, see the
8149 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8152 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8153 * reference for more information on the format of method descriptions.
8156 mono_add_internal_call (const char *name, gconstpointer method)
8160 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8162 mono_icall_unlock ();
8165 #ifndef DISABLE_ICALL_TABLES
8167 #ifdef HAVE_ARRAY_ELEM_INIT
8169 compare_method_imap (const void *key, const void *elem)
8171 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8172 return strcmp (key, method_name);
8176 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8178 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);
8181 return (nameslot - &icall_names_idx [0]);
8185 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8187 gsize slotnum = find_slot_icall (imap, name);
8190 return (gboolean)icall_uses_handles [slotnum];
8194 find_method_icall (const IcallTypeDesc *imap, const char *name)
8196 gsize slotnum = find_slot_icall (imap, name);
8199 return (gpointer)icall_functions [slotnum];
8203 compare_class_imap (const void *key, const void *elem)
8205 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8206 return strcmp (key, class_name);
8209 static const IcallTypeDesc*
8210 find_class_icalls (const char *name)
8212 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);
8215 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8218 #else /* HAVE_ARRAY_ELEM_INIT */
8221 compare_method_imap (const void *key, const void *elem)
8223 const char** method_name = (const char**)elem;
8224 return strcmp (key, *method_name);
8228 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8230 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8233 return nameslot - icall_names;
8237 find_method_icall (const IcallTypeDesc *imap, const char *name)
8239 gsize slotnum = find_slot_icall (imap, name);
8242 return (gpointer)icall_functions [slotnum];
8246 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8248 gsize slotnum = find_slot_icall (imap, name);
8251 return (gboolean)icall_uses_handles [slotnum];
8255 compare_class_imap (const void *key, const void *elem)
8257 const char** class_name = (const char**)elem;
8258 return strcmp (key, *class_name);
8261 static const IcallTypeDesc*
8262 find_class_icalls (const char *name)
8264 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8267 return &icall_type_descs [nameslot - icall_type_names];
8270 #endif /* HAVE_ARRAY_ELEM_INIT */
8272 #endif /* DISABLE_ICALL_TABLES */
8275 * we should probably export this as an helper (handle nested types).
8276 * Returns the number of chars written in buf.
8279 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8281 int nspacelen, cnamelen;
8282 nspacelen = strlen (klass->name_space);
8283 cnamelen = strlen (klass->name);
8284 if (nspacelen + cnamelen + 2 > bufsize)
8287 memcpy (buf, klass->name_space, nspacelen);
8288 buf [nspacelen ++] = '.';
8290 memcpy (buf + nspacelen, klass->name, cnamelen);
8291 buf [nspacelen + cnamelen] = 0;
8292 return nspacelen + cnamelen;
8295 #ifdef DISABLE_ICALL_TABLES
8297 no_icall_table (void)
8299 g_assert_not_reached ();
8304 * mono_lookup_internal_call_full:
8305 * @method: the method to look up
8306 * @uses_handles: out argument if method needs handles around managed objects.
8308 * Returns a pointer to the icall code for the given method. If
8309 * uses_handles is not NULL, it will be set to TRUE if the method
8310 * needs managed objects wrapped using the infrastructure in handle.h
8312 * If the method is not found, warns and returns NULL.
8315 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8320 int typelen = 0, mlen, siglen;
8322 #ifndef DISABLE_ICALL_TABLES
8323 const IcallTypeDesc *imap = NULL;
8326 g_assert (method != NULL);
8328 if (method->is_inflated)
8329 method = ((MonoMethodInflated *) method)->declaring;
8331 if (method->klass->nested_in) {
8332 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8336 mname [pos++] = '/';
8339 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8345 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8350 #ifndef DISABLE_ICALL_TABLES
8351 imap = find_class_icalls (mname);
8354 mname [typelen] = ':';
8355 mname [typelen + 1] = ':';
8357 mlen = strlen (method->name);
8358 memcpy (mname + typelen + 2, method->name, mlen);
8359 sigstart = mname + typelen + 2 + mlen;
8362 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8363 siglen = strlen (tmpsig);
8364 if (typelen + mlen + siglen + 6 > sizeof (mname))
8367 memcpy (sigstart + 1, tmpsig, siglen);
8368 sigstart [siglen + 1] = ')';
8369 sigstart [siglen + 2] = 0;
8374 res = g_hash_table_lookup (icall_hash, mname);
8377 *uses_handles = FALSE;
8378 mono_icall_unlock ();;
8381 /* try without signature */
8383 res = g_hash_table_lookup (icall_hash, mname);
8386 *uses_handles = FALSE;
8387 mono_icall_unlock ();
8391 #ifdef DISABLE_ICALL_TABLES
8392 mono_icall_unlock ();
8393 /* Fail only when the result is actually used */
8394 /* mono_marshal_get_native_wrapper () depends on this */
8395 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8396 return ves_icall_System_String_ctor_RedirectToCreateString;
8398 return no_icall_table;
8400 /* it wasn't found in the static call tables */
8403 *uses_handles = FALSE;
8404 mono_icall_unlock ();
8407 res = find_method_icall (imap, sigstart - mlen);
8410 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8411 mono_icall_unlock ();
8414 /* try _with_ signature */
8416 res = find_method_icall (imap, sigstart - mlen);
8419 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8420 mono_icall_unlock ();
8424 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8425 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8426 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8427 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8428 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");
8429 g_print ("If you see other errors or faults after this message they are probably related\n");
8430 g_print ("and you need to fix your mono install first.\n");
8432 mono_icall_unlock ();
8439 mono_lookup_internal_call (MonoMethod *method)
8441 return mono_lookup_internal_call_full (method, NULL);
8444 #ifdef ENABLE_ICALL_SYMBOL_MAP
8446 func_cmp (gconstpointer key, gconstpointer p)
8448 return (gsize)key - (gsize)*(gsize*)p;
8453 * mono_lookup_icall_symbol:
8455 * Given the icall METHOD, returns its C symbol.
8458 mono_lookup_icall_symbol (MonoMethod *m)
8460 #ifdef DISABLE_ICALL_TABLES
8461 g_assert_not_reached ();
8464 #ifdef ENABLE_ICALL_SYMBOL_MAP
8468 static gconstpointer *functions_sorted;
8469 static const char**symbols_sorted;
8470 static gboolean inited;
8475 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8476 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8477 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8478 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8479 /* Bubble sort the two arrays */
8483 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8484 if (functions_sorted [i] > functions_sorted [i + 1]) {
8487 tmp = functions_sorted [i];
8488 functions_sorted [i] = functions_sorted [i + 1];
8489 functions_sorted [i + 1] = tmp;
8490 tmp = symbols_sorted [i];
8491 symbols_sorted [i] = symbols_sorted [i + 1];
8492 symbols_sorted [i + 1] = tmp;
8499 func = mono_lookup_internal_call (m);
8502 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8506 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8508 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8509 g_assert_not_reached ();
8516 type_from_typename (char *type_name)
8518 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8520 if (!strcmp (type_name, "int"))
8521 klass = mono_defaults.int_class;
8522 else if (!strcmp (type_name, "ptr"))
8523 klass = mono_defaults.int_class;
8524 else if (!strcmp (type_name, "void"))
8525 klass = mono_defaults.void_class;
8526 else if (!strcmp (type_name, "int32"))
8527 klass = mono_defaults.int32_class;
8528 else if (!strcmp (type_name, "uint32"))
8529 klass = mono_defaults.uint32_class;
8530 else if (!strcmp (type_name, "int8"))
8531 klass = mono_defaults.sbyte_class;
8532 else if (!strcmp (type_name, "uint8"))
8533 klass = mono_defaults.byte_class;
8534 else if (!strcmp (type_name, "int16"))
8535 klass = mono_defaults.int16_class;
8536 else if (!strcmp (type_name, "uint16"))
8537 klass = mono_defaults.uint16_class;
8538 else if (!strcmp (type_name, "long"))
8539 klass = mono_defaults.int64_class;
8540 else if (!strcmp (type_name, "ulong"))
8541 klass = mono_defaults.uint64_class;
8542 else if (!strcmp (type_name, "float"))
8543 klass = mono_defaults.single_class;
8544 else if (!strcmp (type_name, "double"))
8545 klass = mono_defaults.double_class;
8546 else if (!strcmp (type_name, "object"))
8547 klass = mono_defaults.object_class;
8548 else if (!strcmp (type_name, "obj"))
8549 klass = mono_defaults.object_class;
8550 else if (!strcmp (type_name, "string"))
8551 klass = mono_defaults.string_class;
8552 else if (!strcmp (type_name, "bool"))
8553 klass = mono_defaults.boolean_class;
8554 else if (!strcmp (type_name, "boolean"))
8555 klass = mono_defaults.boolean_class;
8557 g_error ("%s", type_name);
8558 g_assert_not_reached ();
8560 return &klass->byval_arg;
8564 * LOCKING: Take the corlib image lock.
8566 MonoMethodSignature*
8567 mono_create_icall_signature (const char *sigstr)
8572 MonoMethodSignature *res, *res2;
8573 MonoImage *corlib = mono_defaults.corlib;
8575 mono_image_lock (corlib);
8576 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8577 mono_image_unlock (corlib);
8582 parts = g_strsplit (sigstr, " ", 256);
8591 res = mono_metadata_signature_alloc (corlib, len - 1);
8596 * Under windows, the default pinvoke calling convention is STDCALL but
8599 res->call_convention = MONO_CALL_C;
8602 res->ret = type_from_typename (parts [0]);
8603 for (i = 1; i < len; ++i) {
8604 res->params [i - 1] = type_from_typename (parts [i]);
8609 mono_image_lock (corlib);
8610 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8612 res = res2; /*Value is allocated in the image pool*/
8614 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8615 mono_image_unlock (corlib);
8621 mono_find_jit_icall_by_name (const char *name)
8623 MonoJitICallInfo *info;
8624 g_assert (jit_icall_hash_name);
8627 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8628 mono_icall_unlock ();
8633 mono_find_jit_icall_by_addr (gconstpointer addr)
8635 MonoJitICallInfo *info;
8636 g_assert (jit_icall_hash_addr);
8639 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8640 mono_icall_unlock ();
8646 * mono_get_jit_icall_info:
8648 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8649 * caller should access it while holding the icall lock.
8652 mono_get_jit_icall_info (void)
8654 return jit_icall_hash_name;
8658 * mono_lookup_jit_icall_symbol:
8660 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8663 mono_lookup_jit_icall_symbol (const char *name)
8665 MonoJitICallInfo *info;
8666 const char *res = NULL;
8669 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8671 res = info->c_symbol;
8672 mono_icall_unlock ();
8677 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8680 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8681 mono_icall_unlock ();
8685 * 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
8686 * icalls without wrappers in some cases.
8689 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8691 MonoJitICallInfo *info;
8698 if (!jit_icall_hash_name) {
8699 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8700 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8703 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8704 g_warning ("jit icall already defined \"%s\"\n", name);
8705 g_assert_not_reached ();
8708 info = g_new0 (MonoJitICallInfo, 1);
8713 info->c_symbol = c_symbol;
8714 info->no_raise = no_raise;
8717 info->wrapper = func;
8719 info->wrapper = NULL;
8722 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8723 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8725 mono_icall_unlock ();
8730 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8732 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);