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 // TODO: It's not always set
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionType *
1216 ves_icall_System_Object_GetType (MonoObject *obj)
1219 MonoReflectionType *ret;
1220 #ifndef DISABLE_REMOTING
1221 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1222 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1225 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1227 mono_error_set_pending_exception (&error);
1232 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1234 MonoMethod **dest = (MonoMethod **)data;
1236 /* skip unmanaged frames */
1241 if (!strcmp (m->klass->name_space, "System.Reflection"))
1250 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1252 MonoMethod **dest = (MonoMethod **)data;
1254 /* skip unmanaged frames */
1258 if (m->wrapper_type != MONO_WRAPPER_NONE)
1266 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1277 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1279 MonoMethod **dest = (MonoMethod **)data;
1281 /* skip unmanaged frames */
1285 if (m->wrapper_type != MONO_WRAPPER_NONE)
1293 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1294 || (!strcmp (m->klass->name_space, "System"))))
1304 static MonoReflectionType *
1305 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1307 MonoMethod *m, *dest;
1309 MonoType *type = NULL;
1310 MonoAssembly *assembly = NULL;
1311 gboolean type_resolve = FALSE;
1312 MonoImage *rootimage = NULL;
1314 mono_error_init (error);
1317 * We must compute the calling assembly as type loading must happen under a metadata context.
1318 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1319 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1321 m = mono_method_get_last_managed ();
1323 if (m && m->klass->image != mono_defaults.corlib) {
1324 /* Happens with inlining */
1326 /* Ugly hack: type_from_parsed_name is called from
1327 * System.Type.internal_from_name, which is called most
1328 * directly from System.Type.GetType(string,bool,bool) but
1329 * also indirectly from places such as
1330 * System.Type.GetType(string,func,func) (via
1331 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1332 * so we need to skip over all of those to find the true caller.
1334 * It would be nice if we had stack marks.
1336 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1342 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1343 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1344 * to crash. This only seems to happen in some strange remoting
1345 * scenarios and I was unable to figure out what's happening there.
1346 * Dec 10, 2005 - Martin.
1350 assembly = dest->klass->image->assembly;
1351 type_resolve = TRUE;
1352 rootimage = assembly->image;
1354 g_warning (G_STRLOC);
1356 *caller_assembly = assembly;
1358 if (info->assembly.name)
1359 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1362 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1363 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1364 return_val_if_nok (error, NULL);
1368 // Say we're looking for System.Generic.Dict<int, Local>
1369 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1370 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1371 // is messed up when we go to construct the Local as the type arg...
1373 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1374 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1375 if (!info->assembly.name && !type) {
1377 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1378 return_val_if_nok (error, NULL);
1380 if (assembly && !type && type_resolve) {
1381 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1382 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1383 return_val_if_nok (error, NULL);
1389 return mono_type_get_object_checked (mono_domain_get (), type, error);
1392 ICALL_EXPORT MonoReflectionType*
1393 ves_icall_System_Type_internal_from_name (MonoString *name,
1394 MonoBoolean throwOnError,
1395 MonoBoolean ignoreCase)
1398 MonoTypeNameParse info;
1399 MonoReflectionType *type = NULL;
1401 MonoAssembly *caller_assembly;
1403 char *str = mono_string_to_utf8_checked (name, &error);
1404 if (!is_ok (&error))
1407 parsedOk = mono_reflection_parse_type (str, &info);
1409 /* mono_reflection_parse_type() mangles the string */
1411 mono_reflection_free_type_info (&info);
1413 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1417 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1419 if (!is_ok (&error)) {
1420 mono_reflection_free_type_info (&info);
1426 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1428 if (info.assembly.name)
1429 aname = mono_stringify_assembly_name (&info.assembly);
1430 else if (caller_assembly)
1431 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1433 aname = g_strdup ("");
1434 mono_error_set_type_load_name (&error, tname, aname, "");
1436 mono_reflection_free_type_info (&info);
1442 if (!is_ok (&error)) {
1444 mono_error_set_pending_exception (&error);
1446 mono_error_cleanup (&error);
1454 ICALL_EXPORT MonoReflectionType*
1455 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1458 MonoReflectionType *ret;
1459 MonoDomain *domain = mono_domain_get ();
1461 ret = mono_type_get_object_checked (domain, handle, &error);
1462 mono_error_set_pending_exception (&error);
1467 ICALL_EXPORT MonoType*
1468 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1470 return mono_class_get_type (klass);
1474 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1476 g_ptr_array_free (ptr_array, TRUE);
1480 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1486 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1489 char *res = mono_string_to_utf8_checked (s, &error);
1490 mono_error_set_pending_exception (&error);
1494 /* System.TypeCode */
1513 TYPECODE_STRING = 18
1516 ICALL_EXPORT guint32
1517 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1519 int t = type->type->type;
1521 if (type->type->byref)
1522 return TYPECODE_OBJECT;
1526 case MONO_TYPE_VOID:
1527 return TYPECODE_OBJECT;
1528 case MONO_TYPE_BOOLEAN:
1529 return TYPECODE_BOOLEAN;
1531 return TYPECODE_BYTE;
1533 return TYPECODE_SBYTE;
1535 return TYPECODE_UINT16;
1537 return TYPECODE_INT16;
1538 case MONO_TYPE_CHAR:
1539 return TYPECODE_CHAR;
1543 return TYPECODE_OBJECT;
1545 return TYPECODE_UINT32;
1547 return TYPECODE_INT32;
1549 return TYPECODE_UINT64;
1551 return TYPECODE_INT64;
1553 return TYPECODE_SINGLE;
1555 return TYPECODE_DOUBLE;
1556 case MONO_TYPE_VALUETYPE: {
1557 MonoClass *klass = type->type->data.klass;
1559 if (klass->enumtype) {
1560 t = mono_class_enum_basetype (klass)->type;
1562 } else if (mono_is_corlib_image (klass->image)) {
1563 if (strcmp (klass->name_space, "System") == 0) {
1564 if (strcmp (klass->name, "Decimal") == 0)
1565 return TYPECODE_DECIMAL;
1566 else if (strcmp (klass->name, "DateTime") == 0)
1567 return TYPECODE_DATETIME;
1570 return TYPECODE_OBJECT;
1572 case MONO_TYPE_STRING:
1573 return TYPECODE_STRING;
1574 case MONO_TYPE_SZARRAY:
1575 case MONO_TYPE_ARRAY:
1576 case MONO_TYPE_OBJECT:
1578 case MONO_TYPE_MVAR:
1579 case MONO_TYPE_TYPEDBYREF:
1580 return TYPECODE_OBJECT;
1581 case MONO_TYPE_CLASS:
1583 MonoClass *klass = type->type->data.klass;
1584 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1585 if (strcmp (klass->name, "DBNull") == 0)
1586 return TYPECODE_DBNULL;
1589 return TYPECODE_OBJECT;
1590 case MONO_TYPE_GENERICINST:
1591 return TYPECODE_OBJECT;
1593 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1599 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1601 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1602 return mono_class_enum_basetype (type->data.klass);
1603 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1604 return mono_class_enum_basetype (type->data.generic_class->container_class);
1608 ICALL_EXPORT guint32
1609 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1614 g_assert (type != NULL);
1616 klass = mono_class_from_mono_type (type->type);
1617 klassc = mono_class_from_mono_type (c->type);
1619 if (type->type->byref ^ c->type->byref)
1622 if (type->type->byref) {
1623 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1624 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1626 klass = mono_class_from_mono_type (t);
1627 klassc = mono_class_from_mono_type (ot);
1629 if (mono_type_is_primitive (t)) {
1630 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1631 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1632 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1633 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1634 return t->type == ot->type;
1636 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1639 if (klass->valuetype)
1640 return klass == klassc;
1641 return klass->valuetype == klassc->valuetype;
1644 return mono_class_is_assignable_from (klass, klassc);
1647 ICALL_EXPORT guint32
1648 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1651 MonoClass *klass = mono_class_from_mono_type (type->type);
1652 mono_class_init_checked (klass, &error);
1653 if (!is_ok (&error)) {
1654 mono_error_set_pending_exception (&error);
1657 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1658 mono_error_set_pending_exception (&error);
1662 ICALL_EXPORT guint32
1663 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1665 MonoClass *klass = mono_class_from_mono_type (type->type);
1666 return mono_class_get_flags (klass);
1669 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1670 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1673 MonoClass *klass = field->field->parent;
1674 MonoMarshalType *info;
1678 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1679 if (mono_class_is_gtd (klass) ||
1680 (gklass && gklass->context.class_inst->is_open))
1683 ftype = mono_field_get_type (field->field);
1684 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1687 info = mono_marshal_load_type_info (klass);
1689 for (i = 0; i < info->num_fields; ++i) {
1690 if (info->fields [i].field == field->field) {
1691 if (!info->fields [i].mspec)
1694 MonoReflectionMarshalAsAttribute* obj;
1695 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1696 if (!mono_error_ok (&error))
1697 mono_error_set_pending_exception (&error);
1706 ICALL_EXPORT MonoReflectionField*
1707 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1710 gboolean found = FALSE;
1716 klass = handle->parent;
1718 klass = mono_class_from_mono_type (type);
1720 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1723 /* The managed code will throw the exception */
1727 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1728 mono_error_set_pending_exception (&error);
1732 ICALL_EXPORT MonoReflectionEvent*
1733 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1741 klass = handle->parent;
1743 klass = mono_class_from_mono_type (type);
1745 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1747 /* Managed code will throw an exception */
1751 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1752 mono_error_set_pending_exception (&error);
1757 ICALL_EXPORT MonoReflectionProperty*
1758 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1766 klass = handle->parent;
1768 klass = mono_class_from_mono_type (type);
1770 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1772 /* Managed code will throw an exception */
1776 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1777 mono_error_set_pending_exception (&error);
1781 ICALL_EXPORT MonoArray*
1782 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1785 MonoType *type = mono_field_get_type_checked (field->field, &error);
1788 if (!mono_error_ok (&error)) {
1789 mono_error_set_pending_exception (&error);
1793 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1794 mono_error_set_pending_exception (&error);
1799 vell_icall_get_method_attributes (MonoMethod *method)
1801 return method->flags;
1805 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1808 MonoReflectionType *rt;
1809 MonoDomain *domain = mono_domain_get ();
1810 MonoMethodSignature* sig;
1812 sig = mono_method_signature_checked (method, &error);
1813 if (!mono_error_ok (&error)) {
1814 mono_error_set_pending_exception (&error);
1818 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1819 if (!mono_error_ok (&error)) {
1820 mono_error_set_pending_exception (&error);
1824 MONO_STRUCT_SETREF (info, parent, rt);
1826 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1827 if (!mono_error_ok (&error)) {
1828 mono_error_set_pending_exception (&error);
1832 MONO_STRUCT_SETREF (info, ret, rt);
1834 info->attrs = method->flags;
1835 info->implattrs = method->iflags;
1836 if (sig->call_convention == MONO_CALL_DEFAULT)
1837 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1839 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1844 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1847 ICALL_EXPORT MonoArray*
1848 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1851 MonoDomain *domain = mono_domain_get ();
1853 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1854 mono_error_set_pending_exception (&error);
1858 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1859 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1862 MonoDomain *domain = mono_domain_get ();
1863 MonoReflectionMarshalAsAttribute* res = NULL;
1864 MonoMarshalSpec **mspecs;
1867 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1868 mono_method_get_marshal_info (method, mspecs);
1871 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1872 if (!mono_error_ok (&error)) {
1873 mono_error_set_pending_exception (&error);
1878 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1880 mono_metadata_free_marshal_spec (mspecs [i]);
1887 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1889 MonoClass *parent = field->field->parent;
1890 mono_class_setup_fields (parent);
1892 return field->field->offset - sizeof (MonoObject);
1895 ICALL_EXPORT MonoReflectionType*
1896 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1899 MonoReflectionType *ret;
1902 parent = declaring? field->field->parent: field->klass;
1904 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1905 mono_error_set_pending_exception (&error);
1911 ICALL_EXPORT MonoObject *
1912 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1915 MonoClass *fklass = field->klass;
1916 MonoClassField *cf = field->field;
1917 MonoDomain *domain = mono_object_domain (field);
1919 if (fklass->image->assembly->ref_only) {
1920 mono_set_pending_exception (mono_get_exception_invalid_operation (
1921 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1925 if (mono_security_core_clr_enabled () &&
1926 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1927 mono_error_set_pending_exception (&error);
1931 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1932 mono_error_set_pending_exception (&error);
1937 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1940 MonoClassField *cf = field->field;
1944 if (field->klass->image->assembly->ref_only) {
1945 mono_set_pending_exception (mono_get_exception_invalid_operation (
1946 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1950 if (mono_security_core_clr_enabled () &&
1951 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1952 mono_error_set_pending_exception (&error);
1956 type = mono_field_get_type_checked (cf, &error);
1957 if (!mono_error_ok (&error)) {
1958 mono_error_set_pending_exception (&error);
1962 v = (gchar *) value;
1964 switch (type->type) {
1967 case MONO_TYPE_BOOLEAN:
1970 case MONO_TYPE_CHAR:
1979 case MONO_TYPE_VALUETYPE:
1982 v += sizeof (MonoObject);
1984 case MONO_TYPE_STRING:
1985 case MONO_TYPE_OBJECT:
1986 case MONO_TYPE_CLASS:
1987 case MONO_TYPE_ARRAY:
1988 case MONO_TYPE_SZARRAY:
1991 case MONO_TYPE_GENERICINST: {
1992 MonoGenericClass *gclass = type->data.generic_class;
1993 g_assert (!gclass->context.class_inst->is_open);
1995 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1996 MonoClass *nklass = mono_class_from_mono_type (type);
1997 MonoObject *nullable;
2000 * Convert the boxed vtype into a Nullable structure.
2001 * This is complicated by the fact that Nullables have
2002 * a variable structure.
2004 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2005 if (!mono_error_ok (&error)) {
2006 mono_error_set_pending_exception (&error);
2010 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2012 v = (gchar *)mono_object_unbox (nullable);
2015 if (gclass->container_class->valuetype && (v != NULL))
2016 v += sizeof (MonoObject);
2020 g_error ("type 0x%x not handled in "
2021 "ves_icall_FieldInfo_SetValueInternal", type->type);
2026 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2027 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2028 if (!is_ok (&error)) {
2029 mono_error_set_pending_exception (&error);
2032 if (!vtable->initialized) {
2033 if (!mono_runtime_class_init_full (vtable, &error)) {
2034 mono_error_set_pending_exception (&error);
2038 mono_field_static_set_value (vtable, cf, v);
2040 mono_field_set_value (obj, cf, v);
2045 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2054 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2055 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2059 if (MONO_TYPE_IS_REFERENCE (f->type))
2060 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2062 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2065 ICALL_EXPORT MonoObject *
2066 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2068 MonoObject *o = NULL;
2069 MonoClassField *field = rfield->field;
2071 MonoDomain *domain = mono_object_domain (rfield);
2073 MonoTypeEnum def_type;
2074 const char *def_value;
2078 mono_class_init (field->parent);
2080 t = mono_field_get_type_checked (field, &error);
2081 if (!mono_error_ok (&error)) {
2082 mono_error_set_pending_exception (&error);
2086 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2087 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2091 if (image_is_dynamic (field->parent->image)) {
2092 MonoClass *klass = field->parent;
2093 int fidx = field - klass->fields;
2094 MonoClassExt *ext = mono_class_get_ext (klass);
2097 g_assert (ext->field_def_values);
2098 def_type = ext->field_def_values [fidx].def_type;
2099 def_value = ext->field_def_values [fidx].data;
2101 if (def_type == MONO_TYPE_END) {
2102 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2106 def_value = mono_class_get_field_default_value (field, &def_type);
2107 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2109 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2114 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2118 case MONO_TYPE_BOOLEAN:
2121 case MONO_TYPE_CHAR:
2129 case MONO_TYPE_R8: {
2132 /* boxed value type */
2133 t = g_new0 (MonoType, 1);
2135 klass = mono_class_from_mono_type (t);
2137 o = mono_object_new_checked (domain, klass, &error);
2138 if (!mono_error_ok (&error)) {
2139 mono_error_set_pending_exception (&error);
2142 v = ((gchar *) o) + sizeof (MonoObject);
2143 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2144 if (mono_error_set_pending_exception (&error))
2148 case MONO_TYPE_STRING:
2149 case MONO_TYPE_CLASS:
2150 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2151 if (mono_error_set_pending_exception (&error))
2155 g_assert_not_reached ();
2161 ICALL_EXPORT MonoReflectionType*
2162 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2165 MonoReflectionType *ret;
2168 type = mono_field_get_type_checked (ref_field->field, &error);
2169 if (!mono_error_ok (&error)) {
2170 mono_error_set_pending_exception (&error);
2174 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2175 if (!mono_error_ok (&error)) {
2176 mono_error_set_pending_exception (&error);
2183 /* From MonoProperty.cs */
2185 PInfo_Attributes = 1,
2186 PInfo_GetMethod = 1 << 1,
2187 PInfo_SetMethod = 1 << 2,
2188 PInfo_ReflectedType = 1 << 3,
2189 PInfo_DeclaringType = 1 << 4,
2194 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2197 MonoReflectionType *rt;
2198 MonoReflectionMethod *rm;
2199 MonoDomain *domain = mono_object_domain (property);
2200 const MonoProperty *pproperty = property->property;
2202 if ((req_info & PInfo_ReflectedType) != 0) {
2203 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2204 if (mono_error_set_pending_exception (&error))
2207 MONO_STRUCT_SETREF (info, parent, rt);
2209 if ((req_info & PInfo_DeclaringType) != 0) {
2210 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2211 if (mono_error_set_pending_exception (&error))
2214 MONO_STRUCT_SETREF (info, declaring_type, rt);
2217 if ((req_info & PInfo_Name) != 0)
2218 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2220 if ((req_info & PInfo_Attributes) != 0)
2221 info->attrs = pproperty->attrs;
2223 if ((req_info & PInfo_GetMethod) != 0) {
2224 if (pproperty->get &&
2225 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2226 pproperty->get->klass == property->klass)) {
2227 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2228 if (mono_error_set_pending_exception (&error))
2234 MONO_STRUCT_SETREF (info, get, rm);
2236 if ((req_info & PInfo_SetMethod) != 0) {
2237 if (pproperty->set &&
2238 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2239 pproperty->set->klass == property->klass)) {
2240 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2241 if (mono_error_set_pending_exception (&error))
2247 MONO_STRUCT_SETREF (info, set, rm);
2250 * There may be other methods defined for properties, though, it seems they are not exposed
2251 * in the reflection API
2256 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2259 MonoReflectionType *rt;
2260 MonoReflectionMethod *rm;
2261 MonoDomain *domain = mono_object_domain (event);
2263 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2264 if (mono_error_set_pending_exception (&error))
2267 MONO_STRUCT_SETREF (info, reflected_type, rt);
2269 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2270 if (mono_error_set_pending_exception (&error))
2273 MONO_STRUCT_SETREF (info, declaring_type, rt);
2275 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2276 info->attrs = event->event->attrs;
2278 if (event->event->add) {
2279 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2280 if (mono_error_set_pending_exception (&error))
2286 MONO_STRUCT_SETREF (info, add_method, rm);
2288 if (event->event->remove) {
2289 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2290 if (mono_error_set_pending_exception (&error))
2296 MONO_STRUCT_SETREF (info, remove_method, rm);
2298 if (event->event->raise) {
2299 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2300 if (mono_error_set_pending_exception (&error))
2306 MONO_STRUCT_SETREF (info, raise_method, rm);
2308 #ifndef MONO_SMALL_CONFIG
2309 if (event->event->other) {
2311 while (event->event->other [n])
2313 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2314 if (mono_error_set_pending_exception (&error))
2316 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2318 for (i = 0; i < n; i++) {
2319 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2320 if (mono_error_set_pending_exception (&error))
2322 mono_array_setref (info->other_methods, i, rm);
2329 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2334 mono_class_setup_interfaces (klass, error);
2335 if (!mono_error_ok (error))
2338 for (i = 0; i < klass->interface_count; i++) {
2339 ic = klass->interfaces [i];
2340 g_hash_table_insert (ifaces, ic, ic);
2342 collect_interfaces (ic, ifaces, error);
2343 if (!mono_error_ok (error))
2349 MonoArray *iface_array;
2350 MonoGenericContext *context;
2354 } FillIfaceArrayData;
2357 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2359 MonoReflectionType *rt;
2360 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2361 MonoClass *ic = (MonoClass *)key;
2362 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2364 if (!mono_error_ok (data->error))
2367 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2368 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2369 if (!mono_error_ok (data->error))
2373 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2374 if (!mono_error_ok (data->error))
2377 mono_array_setref (data->iface_array, data->next_idx++, rt);
2380 mono_metadata_free_type (inflated);
2384 get_interfaces_hash (gconstpointer v1)
2386 MonoClass *k = (MonoClass*)v1;
2388 return k->type_token;
2391 ICALL_EXPORT MonoArray*
2392 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2395 MonoClass *klass = mono_class_from_mono_type (type->type);
2397 FillIfaceArrayData data = { 0 };
2400 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2402 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2403 data.context = mono_class_get_context (klass);
2404 klass = mono_class_get_generic_class (klass)->container_class;
2407 for (parent = klass; parent; parent = parent->parent) {
2408 mono_class_setup_interfaces (parent, &error);
2409 if (!mono_error_ok (&error))
2411 collect_interfaces (parent, iface_hash, &error);
2412 if (!mono_error_ok (&error))
2416 data.error = &error;
2417 data.domain = mono_object_domain (type);
2419 len = g_hash_table_size (iface_hash);
2421 g_hash_table_destroy (iface_hash);
2422 if (!data.domain->empty_types) {
2423 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2424 if (!is_ok (&error))
2427 return data.domain->empty_types;
2430 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2431 if (!is_ok (&error))
2433 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2434 if (!mono_error_ok (&error))
2437 g_hash_table_destroy (iface_hash);
2438 return data.iface_array;
2441 g_hash_table_destroy (iface_hash);
2442 mono_error_set_pending_exception (&error);
2447 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2449 gboolean variance_used;
2450 MonoClass *klass = mono_class_from_mono_type (type->type);
2451 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2452 MonoReflectionMethod *member;
2455 int i = 0, len, ioffset;
2459 mono_class_init_checked (klass, &error);
2460 if (mono_error_set_pending_exception (&error))
2462 mono_class_init_checked (iclass, &error);
2463 if (mono_error_set_pending_exception (&error))
2466 mono_class_setup_vtable (klass);
2468 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2472 len = mono_class_num_methods (iclass);
2473 domain = mono_object_domain (type);
2474 MonoArray *targets_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 (targets, (MonoObject*) targets_arr);
2478 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2479 if (mono_error_set_pending_exception (&error))
2481 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2483 while ((method = mono_class_get_methods (iclass, &iter))) {
2484 member = mono_method_get_object_checked (domain, method, iclass, &error);
2485 if (mono_error_set_pending_exception (&error))
2487 mono_array_setref (*methods, i, member);
2488 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2489 if (mono_error_set_pending_exception (&error))
2491 mono_array_setref (*targets, i, member);
2498 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2501 MonoClass *klass = mono_class_from_mono_type (type->type);
2503 mono_class_init_checked (klass, &error);
2504 if (mono_error_set_pending_exception (&error))
2507 if (image_is_dynamic (klass->image)) {
2508 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2509 *packing = tb->packing_size;
2510 *size = tb->class_size;
2512 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2516 ICALL_EXPORT MonoReflectionType*
2517 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2520 MonoReflectionType *ret;
2523 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2524 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2525 mono_error_set_pending_exception (&error);
2529 klass = mono_class_from_mono_type (type->type);
2530 mono_class_init_checked (klass, &error);
2531 if (mono_error_set_pending_exception (&error))
2535 // GetElementType should only return a type for:
2536 // Array Pointer PassedByRef
2537 if (type->type->byref)
2538 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2539 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2540 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2541 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2542 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2546 mono_error_set_pending_exception (&error);
2551 ICALL_EXPORT MonoReflectionType*
2552 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2555 MonoReflectionType *ret;
2557 if (type->type->byref)
2560 MonoClass *klass = mono_class_from_mono_type (type->type);
2564 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2565 mono_error_set_pending_exception (&error);
2570 ICALL_EXPORT MonoBoolean
2571 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2573 return type->type->type == MONO_TYPE_PTR;
2576 ICALL_EXPORT MonoBoolean
2577 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2579 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)));
2582 ICALL_EXPORT MonoBoolean
2583 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2585 return type->type->byref;
2588 ICALL_EXPORT MonoBoolean
2589 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2592 MonoClass *klass = mono_class_from_mono_type (type->type);
2593 mono_class_init_checked (klass, &error);
2594 if (mono_error_set_pending_exception (&error))
2597 return mono_class_is_com_object (klass);
2600 ICALL_EXPORT guint32
2601 ves_icall_reflection_get_token (MonoObject* obj)
2604 guint32 result = mono_reflection_get_token_checked (obj, &error);
2605 mono_error_set_pending_exception (&error);
2609 ICALL_EXPORT MonoReflectionModule*
2610 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2613 MonoReflectionModule *result = NULL;
2614 MonoClass *klass = mono_class_from_mono_type (type->type);
2615 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2616 mono_error_set_pending_exception (&error);
2620 ICALL_EXPORT MonoReflectionAssembly*
2621 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2624 MonoDomain *domain = mono_domain_get ();
2625 MonoClass *klass = mono_class_from_mono_type (type->type);
2626 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2627 mono_error_set_pending_exception (&error);
2631 ICALL_EXPORT MonoReflectionType*
2632 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2635 MonoReflectionType *ret;
2636 MonoDomain *domain = mono_domain_get ();
2639 if (type->type->byref)
2641 if (type->type->type == MONO_TYPE_VAR) {
2642 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2643 klass = param ? param->owner.klass : NULL;
2644 } else if (type->type->type == MONO_TYPE_MVAR) {
2645 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2646 klass = param ? param->owner.method->klass : NULL;
2648 klass = mono_class_from_mono_type (type->type)->nested_in;
2654 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2655 mono_error_set_pending_exception (&error);
2660 ICALL_EXPORT MonoStringHandle
2661 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2663 MonoDomain *domain = mono_domain_get ();
2664 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2665 MonoClass *klass = mono_class_from_mono_type (type);
2668 char *n = g_strdup_printf ("%s&", klass->name);
2669 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2675 return mono_string_new_handle (domain, klass->name, error);
2679 ICALL_EXPORT MonoStringHandle
2680 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2682 MonoDomain *domain = mono_domain_get ();
2683 MonoClass *klass = mono_class_from_mono_type_handle (type);
2685 while (klass->nested_in)
2686 klass = klass->nested_in;
2688 if (klass->name_space [0] == '\0')
2689 return NULL_HANDLE_STRING;
2691 return mono_string_new_handle (domain, klass->name_space, error);
2695 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2699 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2700 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2704 klass = mono_class_from_mono_type (type->type);
2710 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2712 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2715 ICALL_EXPORT MonoArray*
2716 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2719 MonoReflectionType *rt;
2721 MonoClass *klass, *pklass;
2722 MonoDomain *domain = mono_object_domain (type);
2725 klass = mono_class_from_mono_type (type->type);
2727 if (mono_class_is_gtd (klass)) {
2728 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2729 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2730 if (mono_error_set_pending_exception (&error))
2732 for (i = 0; i < container->type_argc; ++i) {
2733 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2735 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2736 if (mono_error_set_pending_exception (&error))
2739 mono_array_setref (res, i, rt);
2741 } else if (mono_class_is_ginst (klass)) {
2742 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2743 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2744 if (mono_error_set_pending_exception (&error))
2746 for (i = 0; i < inst->type_argc; ++i) {
2747 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2748 if (mono_error_set_pending_exception (&error))
2751 mono_array_setref (res, i, rt);
2759 ICALL_EXPORT gboolean
2760 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2764 if (!IS_MONOTYPE (type))
2767 if (type->type->byref)
2770 klass = mono_class_from_mono_type (type->type);
2771 return mono_class_is_gtd (klass);
2774 ICALL_EXPORT MonoReflectionType*
2775 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2778 MonoReflectionType *ret;
2781 if (type->type->byref)
2784 klass = mono_class_from_mono_type (type->type);
2786 if (mono_class_is_gtd (klass)) {
2787 return type; /* check this one */
2789 if (mono_class_is_ginst (klass)) {
2790 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2793 tb = mono_class_get_ref_info (generic_class);
2795 if (generic_class->wastypebuilder && tb)
2796 return (MonoReflectionType *)tb;
2798 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2799 mono_error_set_pending_exception (&error);
2807 ICALL_EXPORT MonoReflectionType*
2808 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2811 MonoReflectionType *ret;
2813 MonoType *geninst, **types;
2816 g_assert (IS_MONOTYPE (type));
2817 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2818 if (mono_error_set_pending_exception (&error))
2821 count = mono_array_length (type_array);
2822 types = g_new0 (MonoType *, count);
2824 for (i = 0; i < count; i++) {
2825 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2826 types [i] = t->type;
2829 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2832 mono_error_set_pending_exception (&error);
2836 klass = mono_class_from_mono_type (geninst);
2838 /*we might inflate to the GTD*/
2839 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2840 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2844 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2845 mono_error_set_pending_exception (&error);
2850 ICALL_EXPORT gboolean
2851 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2855 if (!IS_MONOTYPE (type))
2858 if (type->type->byref)
2861 klass = mono_class_from_mono_type (type->type);
2862 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2866 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2868 if (!IS_MONOTYPE (type))
2871 if (is_generic_parameter (type->type))
2872 return mono_type_get_generic_param_num (type->type);
2876 ICALL_EXPORT MonoGenericParamInfo *
2877 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2879 return mono_generic_param_info (type->type->data.generic_param);
2882 ICALL_EXPORT MonoBoolean
2883 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2885 return is_generic_parameter (type->type);
2888 ICALL_EXPORT MonoReflectionMethod*
2889 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2890 MonoReflectionMethod* generic)
2897 MonoReflectionMethod *ret = NULL;
2899 domain = ((MonoObject *)type)->vtable->domain;
2901 klass = mono_class_from_mono_type (type->type);
2902 mono_class_init_checked (klass, &error);
2903 if (mono_error_set_pending_exception (&error))
2907 while ((method = mono_class_get_methods (klass, &iter))) {
2908 if (method->token == generic->method->token) {
2909 ret = mono_method_get_object_checked (domain, method, klass, &error);
2910 if (mono_error_set_pending_exception (&error))
2918 ICALL_EXPORT MonoReflectionMethod *
2919 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2922 MonoType *type = ref_type->type;
2924 MonoReflectionMethod *ret = NULL;
2926 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2927 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2930 if (type->type == MONO_TYPE_VAR)
2933 method = mono_type_get_generic_param_owner (type)->owner.method;
2936 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2937 if (!mono_error_ok (&error))
2938 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2942 ICALL_EXPORT MonoBoolean
2943 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2945 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2949 ICALL_EXPORT MonoBoolean
2950 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2952 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2957 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2959 MonoDomain *domain = mono_domain_get ();
2960 MonoImage *image = method->method->klass->image;
2961 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2962 MonoTableInfo *tables = image->tables;
2963 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2964 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2965 guint32 im_cols [MONO_IMPLMAP_SIZE];
2966 guint32 scope_token;
2967 const char *import = NULL;
2968 const char *scope = NULL;
2970 if (image_is_dynamic (image)) {
2971 MonoReflectionMethodAux *method_aux =
2972 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2974 import = method_aux->dllentry;
2975 scope = method_aux->dll;
2978 if (!import || !scope) {
2979 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2984 if (piinfo->implmap_idx) {
2985 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2987 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2988 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2989 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2990 scope = mono_metadata_string_heap (image, scope_token);
2994 *flags = piinfo->piflags;
2995 *entry_point = mono_string_new (domain, import);
2996 *dll_name = mono_string_new (domain, scope);
2999 ICALL_EXPORT MonoReflectionMethod *
3000 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3002 MonoMethodInflated *imethod;
3004 MonoReflectionMethod *ret = NULL;
3007 if (method->method->is_generic)
3010 if (!method->method->is_inflated)
3013 imethod = (MonoMethodInflated *) method->method;
3015 result = imethod->declaring;
3016 /* Not a generic method. */
3017 if (!result->is_generic)
3020 if (image_is_dynamic (method->method->klass->image)) {
3021 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3022 MonoReflectionMethod *res;
3025 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3026 * the dynamic case as well ?
3028 mono_image_lock ((MonoImage*)image);
3029 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3030 mono_image_unlock ((MonoImage*)image);
3036 if (imethod->context.class_inst) {
3037 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3038 /*Generic methods gets the context of the GTD.*/
3039 if (mono_class_get_context (klass)) {
3040 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3041 if (!mono_error_ok (&error))
3046 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3048 if (!mono_error_ok (&error))
3049 mono_error_set_pending_exception (&error);
3053 ICALL_EXPORT gboolean
3054 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3056 return mono_method_signature (method->method)->generic_param_count != 0;
3059 ICALL_EXPORT gboolean
3060 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3062 return method->method->is_generic;
3065 ICALL_EXPORT MonoArray*
3066 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3069 MonoReflectionType *rt;
3074 domain = mono_object_domain (method);
3076 if (method->method->is_inflated) {
3077 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3080 count = inst->type_argc;
3081 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3082 if (mono_error_set_pending_exception (&error))
3085 for (i = 0; i < count; i++) {
3086 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3087 if (mono_error_set_pending_exception (&error))
3090 mono_array_setref (res, i, rt);
3097 count = mono_method_signature (method->method)->generic_param_count;
3098 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3099 if (mono_error_set_pending_exception (&error))
3102 for (i = 0; i < count; i++) {
3103 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3104 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3105 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3107 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3108 if (mono_error_set_pending_exception (&error))
3111 mono_array_setref (res, i, rt);
3117 ICALL_EXPORT MonoObject *
3118 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3122 * Invoke from reflection is supposed to always be a virtual call (the API
3123 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3124 * greater flexibility.
3126 MonoMethod *m = method->method;
3127 MonoMethodSignature *sig = mono_method_signature (m);
3130 void *obj = this_arg;
3134 if (mono_security_core_clr_enabled () &&
3135 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3136 mono_error_set_pending_exception (&error);
3140 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3141 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3142 mono_error_cleanup (&error); /* FIXME does this make sense? */
3143 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3148 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3149 if (!is_ok (&error)) {
3150 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3153 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3154 char *target_name = mono_type_get_full_name (m->klass);
3155 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3156 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3158 g_free (target_name);
3162 m = mono_object_get_virtual_method (this_arg, m);
3163 /* must pass the pointer to the value for valuetype methods */
3164 if (m->klass->valuetype)
3165 obj = mono_object_unbox (this_arg);
3166 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3167 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3172 if (sig->ret->byref) {
3173 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"));
3177 pcount = params? mono_array_length (params): 0;
3178 if (pcount != sig->param_count) {
3179 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3183 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3184 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."));
3188 image = m->klass->image;
3189 if (image->assembly->ref_only) {
3190 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."));
3194 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3195 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3199 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3203 intptr_t *lower_bounds;
3204 pcount = mono_array_length (params);
3205 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3206 /* Note: the synthetized array .ctors have int32 as argument type */
3207 for (i = 0; i < pcount; ++i)
3208 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3210 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3211 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3212 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3213 if (!mono_error_ok (&error)) {
3214 mono_error_set_pending_exception (&error);
3218 for (i = 0; i < mono_array_length (arr); ++i) {
3219 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3220 if (!mono_error_ok (&error)) {
3221 mono_error_set_pending_exception (&error);
3224 mono_array_setref_fast (arr, i, subarray);
3226 return (MonoObject*)arr;
3229 if (m->klass->rank == pcount) {
3230 /* Only lengths provided. */
3231 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3232 if (!mono_error_ok (&error)) {
3233 mono_error_set_pending_exception (&error);
3237 return (MonoObject*)arr;
3239 g_assert (pcount == (m->klass->rank * 2));
3240 /* The arguments are lower-bound-length pairs */
3241 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3243 for (i = 0; i < pcount / 2; ++i) {
3244 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3245 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3248 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3249 if (!mono_error_ok (&error)) {
3250 mono_error_set_pending_exception (&error);
3254 return (MonoObject*)arr;
3257 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3258 mono_error_set_pending_exception (&error);
3262 #ifndef DISABLE_REMOTING
3263 ICALL_EXPORT MonoObject *
3264 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3267 MonoDomain *domain = mono_object_domain (method);
3268 MonoMethod *m = method->method;
3269 MonoMethodSignature *sig = mono_method_signature (m);
3270 MonoArray *out_args;
3272 int i, j, outarg_count = 0;
3274 if (m->klass == mono_defaults.object_class) {
3275 if (!strcmp (m->name, "FieldGetter")) {
3276 MonoClass *k = this_arg->vtable->klass;
3280 /* If this is a proxy, then it must be a CBO */
3281 if (k == mono_defaults.transparent_proxy_class) {
3282 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3283 this_arg = tp->rp->unwrapped_server;
3284 g_assert (this_arg);
3285 k = this_arg->vtable->klass;
3288 name = mono_array_get (params, MonoString *, 1);
3289 str = mono_string_to_utf8_checked (name, &error);
3290 if (mono_error_set_pending_exception (&error))
3294 MonoClassField* field = mono_class_get_field_from_name (k, str);
3297 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3298 if (field_klass->valuetype) {
3299 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3300 if (mono_error_set_pending_exception (&error))
3303 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3305 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3306 if (mono_error_set_pending_exception (&error))
3308 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3309 mono_array_setref (out_args, 0, result);
3316 g_assert_not_reached ();
3318 } else if (!strcmp (m->name, "FieldSetter")) {
3319 MonoClass *k = this_arg->vtable->klass;
3325 /* If this is a proxy, then it must be a CBO */
3326 if (k == mono_defaults.transparent_proxy_class) {
3327 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3328 this_arg = tp->rp->unwrapped_server;
3329 g_assert (this_arg);
3330 k = this_arg->vtable->klass;
3333 name = mono_array_get (params, MonoString *, 1);
3334 str = mono_string_to_utf8_checked (name, &error);
3335 if (mono_error_set_pending_exception (&error))
3339 MonoClassField* field = mono_class_get_field_from_name (k, str);
3342 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3343 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3345 if (field_klass->valuetype) {
3346 size = mono_type_size (field->type, &align);
3347 g_assert (size == mono_class_value_size (field_klass, NULL));
3348 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3350 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3353 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3354 if (mono_error_set_pending_exception (&error))
3356 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3365 g_assert_not_reached ();
3370 for (i = 0; i < mono_array_length (params); i++) {
3371 if (sig->params [i]->byref)
3375 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3376 if (mono_error_set_pending_exception (&error))
3379 /* handle constructors only for objects already allocated */
3380 if (!strcmp (method->method->name, ".ctor"))
3381 g_assert (this_arg);
3383 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3384 g_assert (!method->method->klass->valuetype);
3385 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3386 if (mono_error_set_pending_exception (&error))
3389 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3390 if (sig->params [i]->byref) {
3392 arg = mono_array_get (params, gpointer, i);
3393 mono_array_setref (out_args, j, arg);
3398 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3405 read_enum_value (const char *mem, int type)
3408 case MONO_TYPE_BOOLEAN:
3410 return *(guint8*)mem;
3412 return *(gint8*)mem;
3413 case MONO_TYPE_CHAR:
3415 return read16 (mem);
3417 return (gint16) read16 (mem);
3419 return read32 (mem);
3421 return (gint32) read32 (mem);
3424 return read64 (mem);
3426 g_assert_not_reached ();
3432 write_enum_value (char *mem, int type, guint64 value)
3436 case MONO_TYPE_I1: {
3437 guint8 *p = (guint8*)mem;
3443 case MONO_TYPE_CHAR: {
3444 guint16 *p = (guint16 *)mem;
3449 case MONO_TYPE_I4: {
3450 guint32 *p = (guint32 *)mem;
3455 case MONO_TYPE_I8: {
3456 guint64 *p = (guint64 *)mem;
3461 g_assert_not_reached ();
3466 ICALL_EXPORT MonoObject *
3467 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3475 domain = mono_object_domain (enumType);
3476 enumc = mono_class_from_mono_type (enumType->type);
3478 mono_class_init_checked (enumc, &error);
3479 if (mono_error_set_pending_exception (&error))
3482 etype = mono_class_enum_basetype (enumc);
3484 res = mono_object_new_checked (domain, enumc, &error);
3485 if (mono_error_set_pending_exception (&error))
3487 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3492 ICALL_EXPORT MonoBoolean
3493 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3495 int size = mono_class_value_size (a->vtable->klass, NULL);
3496 guint64 a_val = 0, b_val = 0;
3498 memcpy (&a_val, mono_object_unbox (a), size);
3499 memcpy (&b_val, mono_object_unbox (b), size);
3501 return (a_val & b_val) == b_val;
3504 ICALL_EXPORT MonoObject *
3505 ves_icall_System_Enum_get_value (MonoObject *eobj)
3517 g_assert (eobj->vtable->klass->enumtype);
3519 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3520 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3521 if (mono_error_set_pending_exception (&error))
3523 dst = (char *)res + sizeof (MonoObject);
3524 src = (char *)eobj + sizeof (MonoObject);
3525 size = mono_class_value_size (enumc, NULL);
3527 memcpy (dst, src, size);
3532 ICALL_EXPORT MonoReflectionType *
3533 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3536 MonoReflectionType *ret;
3540 klass = mono_class_from_mono_type (type->type);
3541 mono_class_init_checked (klass, &error);
3542 if (mono_error_set_pending_exception (&error))
3545 etype = mono_class_enum_basetype (klass);
3547 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3551 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3552 mono_error_set_pending_exception (&error);
3558 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3560 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3561 gpointer odata = (char *)other + sizeof (MonoObject);
3562 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3563 g_assert (basetype);
3568 if (eobj->vtable->klass != other->vtable->klass)
3571 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3572 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3573 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3576 return me > other ? 1 : -1; \
3579 switch (basetype->type) {
3581 COMPARE_ENUM_VALUES (guint8);
3583 COMPARE_ENUM_VALUES (gint8);
3584 case MONO_TYPE_CHAR:
3586 COMPARE_ENUM_VALUES (guint16);
3588 COMPARE_ENUM_VALUES (gint16);
3590 COMPARE_ENUM_VALUES (guint32);
3592 COMPARE_ENUM_VALUES (gint32);
3594 COMPARE_ENUM_VALUES (guint64);
3596 COMPARE_ENUM_VALUES (gint64);
3600 #undef COMPARE_ENUM_VALUES
3601 /* indicates that the enum was of an unsupported unerlying type */
3606 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3608 gpointer data = (char *)eobj + sizeof (MonoObject);
3609 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3610 g_assert (basetype);
3612 switch (basetype->type) {
3613 case MONO_TYPE_I1: {
3614 gint8 value = *((gint8*)data);
3615 return ((int)value ^ (int)value << 8);
3618 return *((guint8*)data);
3619 case MONO_TYPE_CHAR:
3621 return *((guint16*)data);
3623 case MONO_TYPE_I2: {
3624 gint16 value = *((gint16*)data);
3625 return ((int)(guint16)value | (((int)value) << 16));
3628 return *((guint32*)data);
3630 return *((gint32*)data);
3632 case MONO_TYPE_I8: {
3633 gint64 value = *((gint64*)data);
3634 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3637 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3643 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3645 mono_error_init (error);
3646 HANDLE_FUNCTION_ENTER();
3647 guint64 field_value;
3649 MonoTypeEnum def_type;
3651 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3653 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3655 if (mono_field_is_deleted (field))
3657 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3660 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3662 p = mono_class_get_field_default_value (field, &def_type);
3663 /* len = */ mono_metadata_decode_blob_size (p, &p);
3665 field_value = read_enum_value (p, base_type);
3666 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3668 if (*previous_value > field_value)
3671 *previous_value = field_value;
3674 HANDLE_FUNCTION_RETURN();
3677 ICALL_EXPORT MonoBoolean
3678 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3680 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3681 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3682 guint j = 0, nvalues;
3684 MonoClassField *field;
3686 guint64 previous_value = 0;
3687 gboolean sorted = TRUE;
3689 mono_error_init (error);
3690 mono_class_init_checked (enumc, error);
3691 return_val_if_nok (error, FALSE);
3693 if (!enumc->enumtype) {
3694 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3698 base_type = mono_class_enum_basetype (enumc)->type;
3700 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3701 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3702 return_val_if_nok (error, FALSE);
3703 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3704 return_val_if_nok (error, FALSE);
3707 while ((field = mono_class_get_fields (enumc, &iter))) {
3708 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3712 return_val_if_nok (error, FALSE);
3718 BFLAGS_IgnoreCase = 1,
3719 BFLAGS_DeclaredOnly = 2,
3720 BFLAGS_Instance = 4,
3722 BFLAGS_Public = 0x10,
3723 BFLAGS_NonPublic = 0x20,
3724 BFLAGS_FlattenHierarchy = 0x40,
3725 BFLAGS_InvokeMethod = 0x100,
3726 BFLAGS_CreateInstance = 0x200,
3727 BFLAGS_GetField = 0x400,
3728 BFLAGS_SetField = 0x800,
3729 BFLAGS_GetProperty = 0x1000,
3730 BFLAGS_SetProperty = 0x2000,
3731 BFLAGS_ExactBinding = 0x10000,
3732 BFLAGS_SuppressChangeType = 0x20000,
3733 BFLAGS_OptionalParamBinding = 0x40000
3736 ICALL_EXPORT GPtrArray*
3737 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3740 MonoClass *startklass, *klass;
3743 int (*compare_func) (const char *s1, const char *s2) = NULL;
3744 MonoClassField *field;
3746 if (type->type->byref) {
3747 return g_ptr_array_new ();
3750 mono_error_init (&error);
3752 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3754 klass = startklass = mono_class_from_mono_type (type->type);
3756 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3759 if (mono_class_has_failure (klass)) {
3760 mono_error_set_for_class_failure (&error, klass);
3765 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3766 guint32 flags = mono_field_get_flags (field);
3768 if (mono_field_is_deleted_with_flags (field, flags))
3770 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3771 if (bflags & BFLAGS_Public)
3773 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3774 if (bflags & BFLAGS_NonPublic) {
3781 if (flags & FIELD_ATTRIBUTE_STATIC) {
3782 if (bflags & BFLAGS_Static)
3783 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3786 if (bflags & BFLAGS_Instance)
3793 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3796 g_ptr_array_add (ptr_array, field);
3798 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3804 g_ptr_array_free (ptr_array, TRUE);
3805 mono_error_set_pending_exception (&error);
3810 method_nonpublic (MonoMethod* method, gboolean start_klass)
3812 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3813 case METHOD_ATTRIBUTE_ASSEM:
3814 return (start_klass || mono_defaults.generic_ilist_class);
3815 case METHOD_ATTRIBUTE_PRIVATE:
3817 case METHOD_ATTRIBUTE_PUBLIC:
3825 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3828 MonoClass *startklass;
3832 /*FIXME, use MonoBitSet*/
3833 guint32 method_slots_default [8];
3834 guint32 *method_slots = NULL;
3835 int (*compare_func) (const char *s1, const char *s2) = NULL;
3837 array = g_ptr_array_new ();
3839 mono_error_init (error);
3842 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3844 /* An optimization for calls made from Delegate:CreateDelegate () */
3845 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3846 method = mono_get_delegate_invoke (klass);
3849 g_ptr_array_add (array, method);
3853 mono_class_setup_methods (klass);
3854 mono_class_setup_vtable (klass);
3855 if (mono_class_has_failure (klass))
3858 if (is_generic_parameter (&klass->byval_arg))
3859 nslots = mono_class_get_vtable_size (klass->parent);
3861 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3862 if (nslots >= sizeof (method_slots_default) * 8) {
3863 method_slots = g_new0 (guint32, nslots / 32 + 1);
3865 method_slots = method_slots_default;
3866 memset (method_slots, 0, sizeof (method_slots_default));
3869 mono_class_setup_methods (klass);
3870 mono_class_setup_vtable (klass);
3871 if (mono_class_has_failure (klass))
3875 while ((method = mono_class_get_methods (klass, &iter))) {
3877 if (method->slot != -1) {
3878 g_assert (method->slot < nslots);
3879 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3881 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3882 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3885 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3887 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3888 if (bflags & BFLAGS_Public)
3890 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3896 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3897 if (bflags & BFLAGS_Static)
3898 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3901 if (bflags & BFLAGS_Instance)
3909 if (compare_func (name, method->name))
3914 g_ptr_array_add (array, method);
3916 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3918 if (method_slots != method_slots_default)
3919 g_free (method_slots);
3924 if (method_slots != method_slots_default)
3925 g_free (method_slots);
3926 g_ptr_array_free (array, TRUE);
3928 g_assert (mono_class_has_failure (klass));
3929 mono_error_set_for_class_failure (error, klass);
3933 ICALL_EXPORT GPtrArray*
3934 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3937 GPtrArray *method_array;
3940 klass = mono_class_from_mono_type (type->type);
3941 if (type->type->byref) {
3942 return g_ptr_array_new ();
3945 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3946 mono_error_set_pending_exception (&error);
3947 return method_array;
3950 ICALL_EXPORT GPtrArray*
3951 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3953 MonoClass *startklass, *klass;
3956 gpointer iter = NULL;
3957 GPtrArray *res_array;
3960 if (type->type->byref) {
3961 return g_ptr_array_new ();
3964 klass = startklass = mono_class_from_mono_type (type->type);
3966 mono_class_setup_methods (klass);
3967 if (mono_class_has_failure (klass)) {
3968 mono_error_init (&error);
3969 mono_error_set_for_class_failure (&error, klass);
3970 mono_error_set_pending_exception (&error);
3974 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3977 while ((method = mono_class_get_methods (klass, &iter))) {
3979 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3981 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3982 if (bflags & BFLAGS_Public)
3985 if (bflags & BFLAGS_NonPublic)
3991 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3992 if (bflags & BFLAGS_Static)
3993 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3996 if (bflags & BFLAGS_Instance)
4002 g_ptr_array_add (res_array, method);
4009 property_hash (gconstpointer data)
4011 MonoProperty *prop = (MonoProperty*)data;
4013 return g_str_hash (prop->name);
4017 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4019 if (method1->slot != -1 && method1->slot == method2->slot)
4022 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4023 if (method1->is_inflated)
4024 method1 = ((MonoMethodInflated*) method1)->declaring;
4025 if (method2->is_inflated)
4026 method2 = ((MonoMethodInflated*) method2)->declaring;
4029 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4033 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4035 // Properties are hide-by-name-and-signature
4036 if (!g_str_equal (prop1->name, prop2->name))
4039 /* If we see a property in a generic method, we want to
4040 compare the generic signatures, not the inflated signatures
4041 because we might conflate two properties that were
4045 public T this[T t] { getter { return t; } } // method 1
4046 public U this[U u] { getter { return u; } } // method 2
4049 If we see int Foo<int,int>::Item[int] we need to know if
4050 the indexer came from method 1 or from method 2, and we
4051 shouldn't conflate them. (Bugzilla 36283)
4053 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4056 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4063 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4068 return method_nonpublic (accessor, start_klass);
4071 ICALL_EXPORT GPtrArray*
4072 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4075 MonoClass *startklass, *klass;
4080 int (*compare_func) (const char *s1, const char *s2) = NULL;
4082 GHashTable *properties = NULL;
4083 GPtrArray *res_array;
4085 if (type->type->byref) {
4086 return g_ptr_array_new ();
4089 mono_error_init (&error);
4091 klass = startklass = mono_class_from_mono_type (type->type);
4093 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4095 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4097 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4099 mono_class_setup_methods (klass);
4100 mono_class_setup_vtable (klass);
4101 if (mono_class_has_failure (klass)) {
4102 mono_error_set_for_class_failure (&error, klass);
4107 while ((prop = mono_class_get_properties (klass, &iter))) {
4113 flags = method->flags;
4116 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4117 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4118 if (bflags & BFLAGS_Public)
4120 } else if (bflags & BFLAGS_NonPublic) {
4121 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4122 property_accessor_nonpublic(prop->set, startklass == klass)) {
4129 if (flags & METHOD_ATTRIBUTE_STATIC) {
4130 if (bflags & BFLAGS_Static)
4131 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4134 if (bflags & BFLAGS_Instance)
4142 if (propname != NULL && compare_func (propname, prop->name))
4145 if (g_hash_table_lookup (properties, prop))
4148 g_ptr_array_add (res_array, prop);
4150 g_hash_table_insert (properties, prop, prop);
4152 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4155 g_hash_table_destroy (properties);
4162 g_hash_table_destroy (properties);
4163 g_ptr_array_free (res_array, TRUE);
4165 mono_error_set_pending_exception (&error);
4171 event_hash (gconstpointer data)
4173 MonoEvent *event = (MonoEvent*)data;
4175 return g_str_hash (event->name);
4179 event_equal (MonoEvent *event1, MonoEvent *event2)
4181 // Events are hide-by-name
4182 return g_str_equal (event1->name, event2->name);
4185 ICALL_EXPORT GPtrArray*
4186 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4189 MonoClass *startklass, *klass;
4194 int (*compare_func) (const char *s1, const char *s2) = NULL;
4195 GHashTable *events = NULL;
4196 GPtrArray *res_array;
4198 if (type->type->byref) {
4199 return g_ptr_array_new ();
4202 mono_error_init (&error);
4204 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4206 res_array = g_ptr_array_sized_new (4);
4208 klass = startklass = mono_class_from_mono_type (type->type);
4210 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4212 mono_class_setup_methods (klass);
4213 mono_class_setup_vtable (klass);
4214 if (mono_class_has_failure (klass)) {
4215 mono_error_set_for_class_failure (&error, klass);
4220 while ((event = mono_class_get_events (klass, &iter))) {
4222 method = event->add;
4224 method = event->remove;
4226 method = event->raise;
4228 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4229 if (bflags & BFLAGS_Public)
4231 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4232 if (bflags & BFLAGS_NonPublic)
4237 if (bflags & BFLAGS_NonPublic)
4243 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4244 if (bflags & BFLAGS_Static)
4245 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4248 if (bflags & BFLAGS_Instance)
4253 if (bflags & BFLAGS_Instance)
4258 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4261 if (g_hash_table_lookup (events, event))
4264 g_ptr_array_add (res_array, event);
4266 g_hash_table_insert (events, event, event);
4268 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4271 g_hash_table_destroy (events);
4277 g_hash_table_destroy (events);
4279 g_ptr_array_free (res_array, TRUE);
4281 mono_error_set_pending_exception (&error);
4285 ICALL_EXPORT GPtrArray *
4286 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4292 GPtrArray *res_array;
4294 if (type->type->byref) {
4295 return g_ptr_array_new ();
4298 klass = mono_class_from_mono_type (type->type);
4301 * If a nested type is generic, return its generic type definition.
4302 * Note that this means that the return value is essentially the set
4303 * of nested types of the generic type definition of @klass.
4305 * A note in MSDN claims that a generic type definition can have
4306 * nested types that aren't generic. In any case, the container of that
4307 * nested type would be the generic type definition.
4309 if (mono_class_is_ginst (klass))
4310 klass = mono_class_get_generic_class (klass)->container_class;
4312 res_array = g_ptr_array_new ();
4315 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4317 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4318 if (bflags & BFLAGS_Public)
4321 if (bflags & BFLAGS_NonPublic)
4327 if (str != NULL && strcmp (nested->name, str))
4330 g_ptr_array_add (res_array, &nested->byval_arg);
4336 ICALL_EXPORT MonoReflectionType*
4337 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4340 MonoReflectionType *ret;
4342 MonoType *type = NULL;
4343 MonoTypeNameParse info;
4344 gboolean type_resolve;
4346 /* On MS.NET, this does not fire a TypeResolve event */
4347 type_resolve = TRUE;
4348 str = mono_string_to_utf8_checked (name, &error);
4349 if (mono_error_set_pending_exception (&error))
4351 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4352 if (!mono_reflection_parse_type (str, &info)) {
4354 mono_reflection_free_type_info (&info);
4356 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4359 /*g_print ("failed parse\n");*/
4363 if (info.assembly.name) {
4365 mono_reflection_free_type_info (&info);
4367 /* 1.0 and 2.0 throw different exceptions */
4368 if (mono_defaults.generic_ilist_class)
4369 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4371 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4377 if (module != NULL) {
4378 if (module->image) {
4379 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4380 if (!is_ok (&error)) {
4382 mono_reflection_free_type_info (&info);
4383 mono_error_set_pending_exception (&error);
4390 if (assembly_is_dynamic (assembly->assembly)) {
4391 /* Enumerate all modules */
4392 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4396 if (abuilder->modules) {
4397 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4398 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4399 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4400 if (!is_ok (&error)) {
4402 mono_reflection_free_type_info (&info);
4403 mono_error_set_pending_exception (&error);
4411 if (!type && abuilder->loaded_modules) {
4412 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4413 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4414 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4415 if (!is_ok (&error)) {
4417 mono_reflection_free_type_info (&info);
4418 mono_error_set_pending_exception (&error);
4427 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4428 if (!is_ok (&error)) {
4430 mono_reflection_free_type_info (&info);
4431 mono_error_set_pending_exception (&error);
4436 mono_reflection_free_type_info (&info);
4438 MonoException *e = NULL;
4441 e = mono_get_exception_type_load (name, NULL);
4444 mono_set_pending_exception (e);
4448 if (type->type == MONO_TYPE_CLASS) {
4449 MonoClass *klass = mono_type_get_class (type);
4451 /* need to report exceptions ? */
4452 if (throwOnError && mono_class_has_failure (klass)) {
4453 /* report SecurityException (or others) that occured when loading the assembly */
4454 mono_error_set_for_class_failure (&error, klass);
4455 mono_error_set_pending_exception (&error);
4460 /* g_print ("got it\n"); */
4461 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4462 mono_error_set_pending_exception (&error);
4468 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4471 gchar *shadow_ini_file;
4474 /* Check for shadow-copied assembly */
4475 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4476 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4478 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4479 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4485 g_free (shadow_ini_file);
4486 if (content != NULL) {
4489 *filename = content;
4496 ICALL_EXPORT MonoString *
4497 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4499 MonoDomain *domain = mono_object_domain (assembly);
4500 MonoAssembly *mass = assembly->assembly;
4501 MonoString *res = NULL;
4506 if (g_path_is_absolute (mass->image->name)) {
4507 absolute = g_strdup (mass->image->name);
4508 dirname = g_path_get_dirname (absolute);
4510 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4511 dirname = g_strdup (mass->basedir);
4514 replace_shadow_path (domain, dirname, &absolute);
4517 mono_icall_make_platform_path (absolute);
4520 uri = g_filename_to_uri (absolute, NULL, NULL);
4522 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4523 uri = g_strconcat (prepend, absolute, NULL);
4527 res = mono_string_new (domain, uri);
4534 ICALL_EXPORT MonoBoolean
4535 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4537 MonoAssembly *mass = assembly->assembly;
4539 return mass->in_gac;
4542 ICALL_EXPORT MonoReflectionAssembly*
4543 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4548 MonoImageOpenStatus status;
4549 MonoReflectionAssembly* result = NULL;
4551 name = mono_string_to_utf8_checked (mname, &error);
4552 if (mono_error_set_pending_exception (&error))
4554 res = mono_assembly_load_with_partial_name (name, &status);
4560 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4562 mono_error_set_pending_exception (&error);
4566 ICALL_EXPORT MonoStringHandle
4567 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4569 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4570 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4571 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4574 ICALL_EXPORT MonoBoolean
4575 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4577 return assembly->assembly->ref_only;
4580 ICALL_EXPORT MonoStringHandle
4581 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4583 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4584 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4586 return mono_string_new_handle (domain, assembly->image->version, error);
4589 ICALL_EXPORT MonoReflectionMethod*
4590 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4593 MonoReflectionMethod *res = NULL;
4596 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4600 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4601 if (!mono_error_ok (&error))
4604 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4607 if (!mono_error_ok (&error))
4608 mono_error_set_pending_exception (&error);
4612 ICALL_EXPORT MonoReflectionModule*
4613 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4616 MonoReflectionModule *result = NULL;
4617 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4618 if (!mono_error_ok (&error))
4619 mono_error_set_pending_exception (&error);
4623 ICALL_EXPORT MonoArray*
4624 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4627 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4628 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4629 if (mono_error_set_pending_exception (&error))
4634 for (i = 0; i < table->rows; ++i) {
4635 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4636 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4641 ICALL_EXPORT MonoStringHandle
4642 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4645 guint8 aotid_sum = 0;
4646 MonoDomain* domain = mono_domain_get ();
4648 if (!domain->entry_assembly || !domain->entry_assembly->image)
4651 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4653 for (i = 0; i < 16; ++i)
4654 aotid_sum |= (*aotid)[i];
4659 gchar *guid = mono_guid_to_string((guint8*) aotid);
4660 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4665 static MonoAssemblyName*
4666 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4668 mono_error_init (error);
4669 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4671 mono_assembly_get_assemblyref (image, i, aname);
4672 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4673 /* name and culture are pointers into the image tables, but we need
4674 * real malloc'd strings (so that we can g_free() them later from
4675 * Mono.RuntimeMarshal.FreeAssemblyName) */
4676 aname->name = g_strdup (aname->name);
4677 aname->culture = g_strdup (aname->culture);
4678 /* Don't need the hash value in managed */
4679 aname->hash_value = NULL;
4680 aname->hash_len = 0;
4681 g_assert (aname->public_key == NULL);
4683 /* note: this function doesn't return the codebase on purpose (i.e. it can
4684 be used under partial trust as path information isn't present). */
4688 ICALL_EXPORT GPtrArray*
4689 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4691 mono_error_init (error);
4692 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4693 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4694 MonoImage *image = ass->image;
4696 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4697 int count = t->rows;
4699 GPtrArray *result = g_ptr_array_sized_new (count);
4701 for (int i = 0; i < count; i++) {
4702 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4705 g_ptr_array_add (result, aname);
4710 /* move this in some file in mono/util/ */
4712 g_concat_dir_and_file (const char *dir, const char *file)
4714 g_return_val_if_fail (dir != NULL, NULL);
4715 g_return_val_if_fail (file != NULL, NULL);
4718 * If the directory name doesn't have a / on the end, we need
4719 * to add one so we get a proper path to the file
4721 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4722 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4724 return g_strconcat (dir, file, NULL);
4728 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4731 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4733 guint32 cols [MONO_MANIFEST_SIZE];
4734 guint32 impl, file_idx;
4738 char *n = mono_string_to_utf8_checked (name, &error);
4739 if (mono_error_set_pending_exception (&error))
4742 for (i = 0; i < table->rows; ++i) {
4743 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4744 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4745 if (strcmp (val, n) == 0)
4749 if (i == table->rows)
4752 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4755 * this code should only be called after obtaining the
4756 * ResourceInfo and handling the other cases.
4758 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4759 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4761 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4762 if (mono_error_set_pending_exception (&error) || !module)
4766 module = assembly->assembly->image;
4769 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4770 if (mono_error_set_pending_exception (&error))
4772 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4774 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4777 ICALL_EXPORT gboolean
4778 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4781 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4783 guint32 cols [MONO_MANIFEST_SIZE];
4784 guint32 file_cols [MONO_FILE_SIZE];
4788 n = mono_string_to_utf8_checked (name, &error);
4789 if (mono_error_set_pending_exception (&error))
4791 for (i = 0; i < table->rows; ++i) {
4792 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4793 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4794 if (strcmp (val, n) == 0)
4798 if (i == table->rows)
4801 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4802 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4805 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4806 case MONO_IMPLEMENTATION_FILE:
4807 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4808 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4809 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4810 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4811 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4812 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4815 info->location = RESOURCE_LOCATION_EMBEDDED;
4818 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4819 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4820 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4821 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4822 mono_error_set_assembly_load (&error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4823 mono_error_set_pending_exception (&error);
4826 MonoReflectionAssembly *assm_obj;
4827 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4829 mono_error_set_pending_exception (&error);
4832 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4834 /* Obtain info recursively */
4835 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4836 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4839 case MONO_IMPLEMENTATION_EXP_TYPE:
4840 g_assert_not_reached ();
4848 ICALL_EXPORT MonoObject*
4849 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4852 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4853 MonoArray *result = NULL;
4858 /* check hash if needed */
4860 n = mono_string_to_utf8_checked (name, &error);
4861 if (mono_error_set_pending_exception (&error))
4864 for (i = 0; i < table->rows; ++i) {
4865 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4866 if (strcmp (val, n) == 0) {
4869 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4870 fn = mono_string_new (mono_object_domain (assembly), n);
4872 return (MonoObject*)fn;
4880 for (i = 0; i < table->rows; ++i) {
4881 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4885 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4886 if (mono_error_set_pending_exception (&error))
4891 for (i = 0; i < table->rows; ++i) {
4892 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4893 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4894 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4895 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4900 return (MonoObject*)result;
4903 ICALL_EXPORT MonoArray*
4904 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4907 MonoDomain *domain = mono_domain_get();
4910 int i, j, file_count = 0;
4911 MonoImage **modules;
4912 guint32 module_count, real_module_count;
4913 MonoTableInfo *table;
4914 guint32 cols [MONO_FILE_SIZE];
4915 MonoImage *image = assembly->assembly->image;
4917 g_assert (image != NULL);
4918 g_assert (!assembly_is_dynamic (assembly->assembly));
4920 table = &image->tables [MONO_TABLE_FILE];
4921 file_count = table->rows;
4923 modules = image->modules;
4924 module_count = image->module_count;
4926 real_module_count = 0;
4927 for (i = 0; i < module_count; ++i)
4929 real_module_count ++;
4931 klass = mono_class_get_module_class ();
4932 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
4933 if (mono_error_set_pending_exception (&error))
4936 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
4937 if (mono_error_set_pending_exception (&error))
4940 mono_array_setref (res, 0, image_obj);
4942 for (i = 0; i < module_count; ++i)
4944 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
4945 if (mono_error_set_pending_exception (&error))
4947 mono_array_setref (res, j, rm);
4951 for (i = 0; i < file_count; ++i, ++j) {
4952 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4953 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4954 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
4955 if (mono_error_set_pending_exception (&error))
4957 mono_array_setref (res, j, rm);
4960 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
4961 if (mono_error_set_pending_exception (&error))
4964 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4965 mono_error_set_assembly_load (&error, g_strdup (filename), "%s", "");
4966 mono_error_set_pending_exception (&error);
4969 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
4970 if (mono_error_set_pending_exception (&error))
4972 mono_array_setref (res, j, rm);
4979 ICALL_EXPORT MonoReflectionMethod*
4980 ves_icall_GetCurrentMethod (void)
4982 MonoReflectionMethod *res = NULL;
4985 MonoMethod *m = mono_method_get_last_managed ();
4988 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
4992 while (m->is_inflated)
4993 m = ((MonoMethodInflated*)m)->declaring;
4995 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
4996 mono_error_set_pending_exception (&error);
5002 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5005 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5008 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5009 //method is inflated, we should inflate it on the other class
5010 MonoGenericContext ctx;
5011 ctx.method_inst = inflated->context.method_inst;
5012 ctx.class_inst = inflated->context.class_inst;
5013 if (mono_class_is_ginst (klass))
5014 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5015 else if (mono_class_is_gtd (klass))
5016 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5017 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5018 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5022 mono_class_setup_methods (method->klass);
5023 if (mono_class_has_failure (method->klass))
5025 int mcount = mono_class_get_method_count (method->klass);
5026 for (i = 0; i < mcount; ++i) {
5027 if (method->klass->methods [i] == method) {
5032 mono_class_setup_methods (klass);
5033 if (mono_class_has_failure (klass))
5035 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5036 return klass->methods [offset];
5039 ICALL_EXPORT MonoReflectionMethod*
5040 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5042 MonoReflectionMethod *res = NULL;
5045 if (type && generic_check) {
5046 klass = mono_class_from_mono_type (type);
5047 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5050 if (method->klass != klass) {
5051 method = mono_method_get_equivalent_method (method, klass);
5056 klass = mono_class_from_mono_type (type);
5058 klass = method->klass;
5059 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5060 mono_error_set_pending_exception (&error);
5064 ICALL_EXPORT MonoReflectionMethodBody*
5065 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5068 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5069 mono_error_set_pending_exception (&error);
5073 ICALL_EXPORT MonoReflectionAssembly*
5074 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5077 MonoReflectionAssembly *result;
5078 MonoMethod *dest = NULL;
5080 mono_stack_walk_no_il (get_executing, &dest);
5082 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5084 mono_error_set_pending_exception (&error);
5089 ICALL_EXPORT MonoReflectionAssembly*
5090 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5093 MonoReflectionAssembly *result;
5094 MonoDomain* domain = mono_domain_get ();
5096 if (!domain->entry_assembly)
5099 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5101 mono_error_set_pending_exception (&error);
5105 ICALL_EXPORT MonoReflectionAssembly*
5106 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5111 MonoReflectionAssembly *result;
5114 mono_stack_walk_no_il (get_executing, &dest);
5116 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5120 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5123 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5125 mono_error_set_pending_exception (&error);
5129 ICALL_EXPORT MonoStringHandle
5130 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5131 gboolean assembly_qualified, MonoError *error)
5133 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5134 MonoType *type = MONO_HANDLE_RAW (object)->type;
5135 MonoTypeNameFormat format;
5136 MonoStringHandle res;
5140 format = assembly_qualified ?
5141 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5142 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5144 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5146 name = mono_type_get_name_full (type, format);
5148 return NULL_HANDLE_STRING;
5150 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5152 return NULL_HANDLE_STRING;
5155 res = mono_string_new_handle (domain, name, error);
5162 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5165 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5167 mono_class_init_checked (klass, &error);
5168 mono_error_set_pending_exception (&error);
5169 return mono_security_core_clr_class_level (klass);
5173 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5175 MonoClassField *field = rfield->field;
5176 return mono_security_core_clr_field_level (field, TRUE);
5180 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5182 MonoMethod *method = rfield->method;
5183 return mono_security_core_clr_method_level (method, TRUE);
5186 ICALL_EXPORT MonoString *
5187 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5189 MonoDomain *domain = mono_object_domain (assembly);
5190 MonoAssembly *mass = assembly->assembly;
5194 name = mono_stringify_assembly_name (&mass->aname);
5195 res = mono_string_new (domain, name);
5201 ICALL_EXPORT MonoAssemblyName *
5202 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5204 return &mass->aname;
5208 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5211 MonoImageOpenStatus status = MONO_IMAGE_OK;
5212 char *codebase = NULL;
5217 mono_error_init (error);
5219 filename = mono_string_handle_to_utf8 (fname, error);
5220 return_if_nok (error);
5222 dirname = g_path_get_dirname (filename);
5223 replace_shadow_path (mono_domain_get (), dirname, &filename);
5226 image = mono_image_open (filename, &status);
5229 if (status == MONO_IMAGE_IMAGE_INVALID)
5230 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5232 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5237 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5239 mono_image_close (image);
5241 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5245 if (filename != NULL && *filename != '\0') {
5248 codebase = g_strdup (filename);
5250 mono_icall_make_platform_path (codebase);
5252 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5254 result = g_strconcat (prepend, codebase, NULL);
5258 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5261 mono_image_close (image);
5265 ICALL_EXPORT MonoBoolean
5266 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5267 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5269 MonoBoolean result = FALSE;
5270 MonoDeclSecurityEntry entry;
5272 /* SecurityAction.RequestMinimum */
5273 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5274 *minimum = entry.blob;
5275 *minLength = entry.size;
5278 /* SecurityAction.RequestOptional */
5279 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5280 *optional = entry.blob;
5281 *optLength = entry.size;
5284 /* SecurityAction.RequestRefuse */
5285 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5286 *refused = entry.blob;
5287 *refLength = entry.size;
5295 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5297 guint32 attrs, visibility;
5299 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5300 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5301 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5304 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5310 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5312 mono_error_init (error);
5313 HANDLE_FUNCTION_ENTER ();
5314 MonoError klass_error;
5315 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5318 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5319 return_if_nok (error);
5321 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5323 MonoException *ex = mono_error_convert_to_exception (error);
5324 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5326 HANDLE_FUNCTION_RETURN ();
5329 static MonoArrayHandle
5330 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5332 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5335 mono_error_init (error);
5337 /* we start the count from 1 because we skip the special type <Module> */
5340 for (i = 1; i < tdef->rows; ++i) {
5341 if (mono_module_type_is_visible (tdef, image, i + 1))
5345 count = tdef->rows - 1;
5347 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5348 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5349 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5350 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5352 for (i = 1; i < tdef->rows; ++i) {
5353 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5354 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5355 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5364 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5366 HANDLE_FUNCTION_ENTER ();
5367 mono_error_init (error);
5368 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5369 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5373 /* Append the new types to the end of the array */
5374 if (mono_array_handle_length (res2) > 0) {
5377 len1 = mono_array_handle_length (res);
5378 len2 = mono_array_handle_length (res2);
5380 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5384 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5385 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5386 MONO_HANDLE_ASSIGN (res, res3);
5388 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5392 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5393 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5394 MONO_HANDLE_ASSIGN (exceptions, ex3);
5397 HANDLE_FUNCTION_RETURN ();
5401 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5403 HANDLE_FUNCTION_ENTER ();
5404 MonoError unboxed_error;
5405 mono_error_init (&unboxed_error);
5406 mono_error_set_for_class_failure (&unboxed_error, klass);
5408 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5409 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5410 HANDLE_FUNCTION_RETURN ();
5413 ICALL_EXPORT MonoArrayHandle
5414 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5416 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5419 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5420 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5422 g_assert (!assembly_is_dynamic (assembly));
5423 MonoImage *image = assembly->image;
5424 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5425 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5426 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5428 /* Append data from all modules in the assembly */
5429 for (i = 0; i < table->rows; ++i) {
5430 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5431 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5432 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5435 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5436 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5441 /* the ReflectionTypeLoadException must have all the types (Types property),
5442 * NULL replacing types which throws an exception. The LoaderException must
5443 * contain all exceptions for NULL items.
5446 int len = mono_array_handle_length (res);
5450 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5451 for (i = 0; i < len; i++) {
5452 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5454 if (!MONO_HANDLE_IS_NULL (t)) {
5455 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5456 if ((klass != NULL) && mono_class_has_failure (klass)) {
5457 /* keep the class in the list */
5458 list = g_list_append (list, klass);
5459 /* and replace Type with NULL */
5460 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5467 if (list || ex_count) {
5469 int j, length = g_list_length (list) + ex_count;
5471 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5472 if (!is_ok (error)) {
5474 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5476 /* Types for which mono_class_get_checked () succeeded */
5477 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5478 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5479 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5481 /* Types for which it don't */
5482 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5483 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5484 if (!MONO_HANDLE_IS_NULL (exc)) {
5485 g_assert (i < length);
5486 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5493 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5494 if (!is_ok (error)) {
5495 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5497 mono_error_set_exception_handle (error, exc);
5498 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5505 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5507 mono_assembly_name_free (aname);
5512 ICALL_EXPORT gboolean
5513 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5515 *is_version_definited = *is_token_defined = FALSE;
5517 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5520 ICALL_EXPORT MonoReflectionTypeHandle
5521 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5523 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5524 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5529 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5531 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5532 /* These images do not have a global type */
5535 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5539 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5545 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5547 /*if (module->image)
5548 mono_image_close (module->image);*/
5551 ICALL_EXPORT MonoStringHandle
5552 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5554 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5555 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5558 return mono_string_new_handle (domain, image->guid, error);
5562 static inline gpointer
5563 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5565 return (gpointer) (-1);
5567 #endif /* HOST_WIN32 */
5569 ICALL_EXPORT gpointer
5570 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5572 return mono_icall_module_get_hinstance (module);
5576 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5578 if (image_is_dynamic (image)) {
5579 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5580 *pe_kind = dyn->pe_kind;
5581 *machine = dyn->machine;
5584 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5585 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5590 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5592 return (image->md_version_major << 16) | (image->md_version_minor);
5595 ICALL_EXPORT MonoArrayHandle
5596 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5598 mono_error_init (error);
5600 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5601 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5604 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5607 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5608 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5609 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5611 int n = mono_array_handle_length (exceptions);
5612 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5613 for (int i = 0; i < n; ++i) {
5614 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5615 if (!MONO_HANDLE_IS_NULL (ex)) {
5616 mono_error_set_exception_handle (error, ex);
5617 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5625 mono_memberref_is_method (MonoImage *image, guint32 token)
5627 if (!image_is_dynamic (image)) {
5628 guint32 cols [MONO_MEMBERREF_SIZE];
5630 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5631 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5632 mono_metadata_decode_blob_size (sig, &sig);
5633 return (*sig != 0x6);
5636 MonoClass *handle_class;
5638 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5639 mono_error_cleanup (&error); /* just probing, ignore error */
5643 return mono_defaults.methodhandle_class == handle_class;
5648 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5651 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5652 mono_array_addr (type_args, MonoType*, 0));
5654 context->class_inst = NULL;
5656 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5657 mono_array_addr (method_args, MonoType*, 0));
5659 context->method_inst = NULL;
5662 ICALL_EXPORT MonoType*
5663 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5666 int table = mono_metadata_token_table (token);
5667 int index = mono_metadata_token_index (token);
5668 MonoGenericContext context;
5671 *resolve_error = ResolveTokenError_Other;
5673 /* Validate token */
5674 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5675 (table != MONO_TABLE_TYPESPEC)) {
5676 *resolve_error = ResolveTokenError_BadTable;
5680 if (image_is_dynamic (image)) {
5681 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5682 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5683 mono_error_cleanup (&error);
5684 return klass ? &klass->byval_arg : NULL;
5687 init_generic_context_from_args (&context, type_args, method_args);
5688 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5689 mono_error_cleanup (&error);
5690 return klass ? &klass->byval_arg : NULL;
5693 if ((index <= 0) || (index > image->tables [table].rows)) {
5694 *resolve_error = ResolveTokenError_OutOfRange;
5698 init_generic_context_from_args (&context, type_args, method_args);
5699 klass = mono_class_get_checked (image, token, &error);
5701 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5702 if (!mono_error_ok (&error)) {
5703 mono_error_set_pending_exception (&error);
5708 return &klass->byval_arg;
5713 ICALL_EXPORT MonoMethod*
5714 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5717 int table = mono_metadata_token_table (token);
5718 int index = mono_metadata_token_index (token);
5719 MonoGenericContext context;
5722 *resolve_error = ResolveTokenError_Other;
5724 /* Validate token */
5725 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5726 (table != MONO_TABLE_MEMBERREF)) {
5727 *resolve_error = ResolveTokenError_BadTable;
5731 if (image_is_dynamic (image)) {
5732 if (table == MONO_TABLE_METHOD) {
5733 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5734 mono_error_cleanup (&error);
5738 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5739 *resolve_error = ResolveTokenError_BadTable;
5743 init_generic_context_from_args (&context, type_args, method_args);
5744 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5745 mono_error_cleanup (&error);
5749 if ((index <= 0) || (index > image->tables [table].rows)) {
5750 *resolve_error = ResolveTokenError_OutOfRange;
5753 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5754 *resolve_error = ResolveTokenError_BadTable;
5758 init_generic_context_from_args (&context, type_args, method_args);
5759 method = mono_get_method_checked (image, token, NULL, &context, &error);
5760 mono_error_set_pending_exception (&error);
5765 ICALL_EXPORT MonoString*
5766 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5769 int index = mono_metadata_token_index (token);
5771 *resolve_error = ResolveTokenError_Other;
5773 /* Validate token */
5774 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5775 *resolve_error = ResolveTokenError_BadTable;
5779 if (image_is_dynamic (image)) {
5780 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5781 mono_error_cleanup (&error);
5785 if ((index <= 0) || (index >= image->heap_us.size)) {
5786 *resolve_error = ResolveTokenError_OutOfRange;
5790 /* FIXME: What to do if the index points into the middle of a string ? */
5792 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5793 mono_error_set_pending_exception (&error);
5797 ICALL_EXPORT MonoClassField*
5798 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5802 int table = mono_metadata_token_table (token);
5803 int index = mono_metadata_token_index (token);
5804 MonoGenericContext context;
5805 MonoClassField *field;
5807 *resolve_error = ResolveTokenError_Other;
5809 /* Validate token */
5810 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5811 *resolve_error = ResolveTokenError_BadTable;
5815 if (image_is_dynamic (image)) {
5816 if (table == MONO_TABLE_FIELD) {
5817 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5818 mono_error_cleanup (&error);
5822 if (mono_memberref_is_method (image, token)) {
5823 *resolve_error = ResolveTokenError_BadTable;
5827 init_generic_context_from_args (&context, type_args, method_args);
5828 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5829 mono_error_cleanup (&error);
5833 if ((index <= 0) || (index > image->tables [table].rows)) {
5834 *resolve_error = ResolveTokenError_OutOfRange;
5837 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5838 *resolve_error = ResolveTokenError_BadTable;
5842 init_generic_context_from_args (&context, type_args, method_args);
5843 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5844 mono_error_set_pending_exception (&error);
5850 ICALL_EXPORT MonoObject*
5851 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5855 int table = mono_metadata_token_table (token);
5857 *error = ResolveTokenError_Other;
5860 case MONO_TABLE_TYPEDEF:
5861 case MONO_TABLE_TYPEREF:
5862 case MONO_TABLE_TYPESPEC: {
5863 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5865 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5866 mono_error_set_pending_exception (&merror);
5873 case MONO_TABLE_METHOD:
5874 case MONO_TABLE_METHODSPEC: {
5875 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5877 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5878 mono_error_set_pending_exception (&merror);
5884 case MONO_TABLE_FIELD: {
5885 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5887 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5888 mono_error_set_pending_exception (&merror);
5894 case MONO_TABLE_MEMBERREF:
5895 if (mono_memberref_is_method (image, token)) {
5896 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5898 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5899 mono_error_set_pending_exception (&merror);
5906 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5908 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5909 mono_error_set_pending_exception (&merror);
5918 *error = ResolveTokenError_BadTable;
5924 ICALL_EXPORT MonoArray*
5925 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5928 int table = mono_metadata_token_table (token);
5929 int idx = mono_metadata_token_index (token);
5930 MonoTableInfo *tables = image->tables;
5935 *resolve_error = ResolveTokenError_OutOfRange;
5937 /* FIXME: Support other tables ? */
5938 if (table != MONO_TABLE_STANDALONESIG)
5941 if (image_is_dynamic (image))
5944 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5947 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5949 ptr = mono_metadata_blob_heap (image, sig);
5950 len = mono_metadata_decode_blob_size (ptr, &ptr);
5952 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
5953 if (mono_error_set_pending_exception (&error))
5955 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5959 ICALL_EXPORT MonoBoolean
5960 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
5966 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5972 check_for_invalid_type (MonoClass *klass, MonoError *error)
5976 mono_error_init (error);
5978 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
5981 name = mono_type_get_full_name (klass);
5982 mono_error_set_type_load_name (error, name, g_strdup (""), "");
5984 ICALL_EXPORT MonoReflectionType *
5985 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
5988 MonoReflectionType *ret;
5989 MonoClass *klass, *aklass;
5991 klass = mono_class_from_mono_type (type->type);
5992 check_for_invalid_type (klass, &error);
5993 if (mono_error_set_pending_exception (&error))
5996 if (rank == 0) //single dimentional array
5997 aklass = mono_array_class_get (klass, 1);
5999 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6001 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6002 mono_error_set_pending_exception (&error);
6007 ICALL_EXPORT MonoReflectionType *
6008 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6011 MonoReflectionType *ret;
6014 klass = mono_class_from_mono_type (type->type);
6015 mono_class_init_checked (klass, &error);
6016 if (mono_error_set_pending_exception (&error))
6019 check_for_invalid_type (klass, &error);
6020 if (mono_error_set_pending_exception (&error))
6023 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6024 mono_error_set_pending_exception (&error);
6029 ICALL_EXPORT MonoReflectionType *
6030 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6033 MonoReflectionType *ret;
6034 MonoClass *klass, *pklass;
6036 klass = mono_class_from_mono_type (type->type);
6037 mono_class_init_checked (klass, &error);
6038 if (mono_error_set_pending_exception (&error))
6040 check_for_invalid_type (klass, &error);
6041 if (mono_error_set_pending_exception (&error))
6044 pklass = mono_ptr_class_get (type->type);
6046 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6047 mono_error_set_pending_exception (&error);
6052 ICALL_EXPORT MonoObject *
6053 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6054 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6057 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6058 MonoObject *delegate;
6060 MonoMethod *method = info->method;
6061 MonoMethodSignature *sig = mono_method_signature(method);
6063 mono_class_init_checked (delegate_class, &error);
6064 if (mono_error_set_pending_exception (&error))
6067 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6068 /* FIXME improve this exception message */
6069 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6071 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6072 mono_error_set_pending_exception (&error);
6076 if (mono_security_core_clr_enabled ()) {
6077 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6078 if (throwOnBindFailure)
6079 mono_error_set_pending_exception (&error);
6081 mono_error_cleanup (&error);
6086 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6087 if (!method->is_inflated) {
6088 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"));
6093 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6094 if (mono_error_set_pending_exception (&error))
6097 if (method_is_dynamic (method)) {
6098 /* Creating a trampoline would leak memory */
6099 func = mono_compile_method_checked (method, &error);
6100 if (mono_error_set_pending_exception (&error))
6103 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6104 method = mono_object_get_virtual_method (target, method);
6105 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6106 if (mono_error_set_pending_exception (&error))
6108 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6111 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6112 if (mono_error_set_pending_exception (&error))
6117 ICALL_EXPORT MonoMulticastDelegate *
6118 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6121 MonoMulticastDelegate *ret;
6123 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6125 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6126 if (mono_error_set_pending_exception (&error))
6129 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6134 ICALL_EXPORT MonoReflectionMethod*
6135 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6137 MonoReflectionMethod *ret = NULL;
6139 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6140 mono_error_set_pending_exception (&error);
6146 static inline gint32
6147 mono_array_get_byte_length (MonoArray *array)
6153 klass = array->obj.vtable->klass;
6155 if (array->bounds == NULL)
6156 length = array->max_length;
6159 for (i = 0; i < klass->rank; ++ i)
6160 length *= array->bounds [i].length;
6163 switch (klass->element_class->byval_arg.type) {
6166 case MONO_TYPE_BOOLEAN:
6170 case MONO_TYPE_CHAR:
6178 return length * sizeof (gpointer);
6189 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6191 return mono_array_get_byte_length (array);
6195 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6197 return mono_array_get (array, gint8, idx);
6201 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6203 mono_array_set (array, gint8, idx, value);
6206 ICALL_EXPORT MonoBoolean
6207 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6209 guint8 *src_buf, *dest_buf;
6212 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6216 g_assert (count >= 0);
6218 /* This is called directly from the class libraries without going through the managed wrapper */
6219 MONO_CHECK_ARG_NULL (src, FALSE);
6220 MONO_CHECK_ARG_NULL (dest, FALSE);
6222 /* watch out for integer overflow */
6223 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6226 src_buf = (guint8 *)src->vector + src_offset;
6227 dest_buf = (guint8 *)dest->vector + dest_offset;
6230 memcpy (dest_buf, src_buf, count);
6232 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6237 #ifndef DISABLE_REMOTING
6238 ICALL_EXPORT MonoObject *
6239 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6242 MonoDomain *domain = mono_object_domain (this_obj);
6244 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6245 MonoTransparentProxy *tp;
6249 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6250 if (mono_error_set_pending_exception (&error))
6253 tp = (MonoTransparentProxy*) res;
6255 MONO_OBJECT_SETREF (tp, rp, rp);
6256 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6257 klass = mono_class_from_mono_type (type);
6259 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6260 mono_class_setup_vtable (klass);
6261 if (mono_class_has_failure (klass)) {
6262 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6266 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6267 if (mono_error_set_pending_exception (&error))
6269 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6270 if (mono_error_set_pending_exception (&error))
6273 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6274 if (mono_error_set_pending_exception (&error))
6279 ICALL_EXPORT MonoReflectionType *
6280 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6283 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6284 mono_error_set_pending_exception (&error);
6290 /* System.Environment */
6293 ves_icall_System_Environment_get_UserName (void)
6295 /* using glib is more portable */
6296 return mono_string_new (mono_domain_get (), g_get_user_name ());
6301 mono_icall_get_machine_name (void)
6303 #if !defined(DISABLE_SOCKETS)
6307 #if defined _SC_HOST_NAME_MAX
6308 n = sysconf (_SC_HOST_NAME_MAX);
6312 buf = g_malloc (n+1);
6314 if (gethostname (buf, n) == 0){
6316 result = mono_string_new (mono_domain_get (), buf);
6323 return mono_string_new (mono_domain_get (), "mono");
6326 #endif /* !HOST_WIN32 */
6328 ICALL_EXPORT MonoString *
6329 ves_icall_System_Environment_get_MachineName (void)
6331 return mono_icall_get_machine_name ();
6336 mono_icall_get_platform (void)
6338 #if defined(__MACH__)
6341 // Notice that the value is hidden from user code, and only exposed
6342 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6343 // define and making assumptions based on Unix/128/4 values before there
6344 // was a MacOS define. Lots of code would assume that not-Unix meant
6345 // Windows, but in this case, it would be OSX.
6353 #endif /* !HOST_WIN32 */
6356 ves_icall_System_Environment_get_Platform (void)
6358 return mono_icall_get_platform ();
6362 static inline MonoString *
6363 mono_icall_get_new_line (void)
6365 return mono_string_new (mono_domain_get (), "\n");
6367 #endif /* !HOST_WIN32 */
6369 ICALL_EXPORT MonoString *
6370 ves_icall_System_Environment_get_NewLine (void)
6372 return mono_icall_get_new_line ();
6376 static inline MonoBoolean
6377 mono_icall_is_64bit_os (void)
6379 #if SIZEOF_VOID_P == 8
6382 #if defined(HAVE_SYS_UTSNAME_H)
6383 struct utsname name;
6385 if (uname (&name) >= 0) {
6386 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6392 #endif /* !HOST_WIN32 */
6394 ICALL_EXPORT MonoBoolean
6395 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6397 return mono_icall_is_64bit_os ();
6400 ICALL_EXPORT MonoStringHandle
6401 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6405 if (utf8_name == NULL)
6406 return NULL_HANDLE_STRING;
6408 value = g_getenv (utf8_name);
6411 return NULL_HANDLE_STRING;
6413 return mono_string_new_handle (mono_domain_get (), value, error);
6417 * There is no standard way to get at environ.
6420 #ifndef __MINGW32_VERSION
6421 #if defined(__APPLE__)
6422 #if defined (TARGET_OSX)
6423 /* Apple defines this in crt_externs.h but doesn't provide that header for
6424 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6425 * in fact exist on all implementations (so far)
6427 gchar ***_NSGetEnviron(void);
6428 #define environ (*_NSGetEnviron())
6430 static char *mono_environ[1] = { NULL };
6431 #define environ mono_environ
6432 #endif /* defined (TARGET_OSX) */
6440 ICALL_EXPORT MonoArray *
6441 ves_icall_System_Environment_GetCoomandLineArgs (void)
6444 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6445 mono_error_set_pending_exception (&error);
6451 mono_icall_get_environment_variable_names (void)
6461 for (e = environ; *e != 0; ++ e)
6464 domain = mono_domain_get ();
6465 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6466 if (mono_error_set_pending_exception (&error))
6470 for (e = environ; *e != 0; ++ e) {
6471 parts = g_strsplit (*e, "=", 2);
6473 str = mono_string_new (domain, *parts);
6474 mono_array_setref (names, n, str);
6484 #endif /* !HOST_WIN32 */
6486 ICALL_EXPORT MonoArray *
6487 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6489 return mono_icall_get_environment_variable_names ();
6494 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6496 gchar *utf8_name, *utf8_value;
6499 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6500 if (mono_error_set_pending_exception (&error))
6503 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6504 g_unsetenv (utf8_name);
6509 utf8_value = mono_string_to_utf8_checked (value, &error);
6510 if (!mono_error_ok (&error)) {
6512 mono_error_set_pending_exception (&error);
6515 g_setenv (utf8_name, utf8_value, TRUE);
6518 g_free (utf8_value);
6520 #endif /* !HOST_WIN32 */
6523 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6525 mono_icall_set_environment_variable (name, value);
6529 ves_icall_System_Environment_Exit (int result)
6531 mono_environment_exitcode_set (result);
6533 /* FIXME: There are some cleanup hangs that should be worked out, but
6534 * if the program is going to exit, everything will be cleaned up when
6535 * NaCl exits anyway.
6537 #ifndef __native_client__
6538 if (!mono_runtime_try_shutdown ())
6539 mono_thread_exit ();
6541 /* Suspend all managed threads since the runtime is going away */
6542 mono_thread_suspend_all_other_threads ();
6544 mono_runtime_quit ();
6547 /* we may need to do some cleanup here... */
6551 ICALL_EXPORT MonoStringHandle
6552 ves_icall_System_Environment_GetGacPath (MonoError *error)
6554 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6558 static inline MonoString *
6559 mono_icall_get_windows_folder_path (int folder)
6561 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6562 return mono_string_new (mono_domain_get (), "");
6564 #endif /* !HOST_WIN32 */
6566 ICALL_EXPORT MonoString*
6567 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6569 return mono_icall_get_windows_folder_path (folder);
6572 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6574 mono_icall_get_logical_drives (void)
6577 gunichar2 buf [256], *ptr, *dname;
6579 guint initial_size = 127, size = 128;
6582 MonoString *drivestr;
6583 MonoDomain *domain = mono_domain_get ();
6589 while (size > initial_size) {
6590 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6591 if (size > initial_size) {
6594 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6595 initial_size = size;
6609 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6610 if (mono_error_set_pending_exception (&error))
6617 while (*u16) { u16++; len ++; }
6618 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6619 if (mono_error_set_pending_exception (&error))
6622 mono_array_setref (result, ndrives++, drivestr);
6632 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6634 ICALL_EXPORT MonoArray *
6635 ves_icall_System_Environment_GetLogicalDrives (void)
6637 return mono_icall_get_logical_drives ();
6640 ICALL_EXPORT MonoString *
6641 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6644 gunichar2 volume_name [MAX_PATH + 1];
6646 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6648 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6649 mono_error_set_pending_exception (&error);
6653 ICALL_EXPORT MonoStringHandle
6654 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6656 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6659 static const char *encodings [] = {
6661 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6662 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6663 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6665 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6666 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6667 "x_unicode_2_0_utf_7",
6669 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6670 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6672 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6675 "unicodefffe", "utf_16be",
6682 * Returns the internal codepage, if the value of "int_code_page" is
6683 * 1 at entry, and we can not compute a suitable code page number,
6684 * returns the code page as a string
6686 ICALL_EXPORT MonoString*
6687 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6692 char *codepage = NULL;
6694 int want_name = *int_code_page;
6697 *int_code_page = -1;
6699 g_get_charset (&cset);
6700 c = codepage = g_strdup (cset);
6701 for (c = codepage; *c; c++){
6702 if (isascii (*c) && isalpha (*c))
6707 /* g_print ("charset: %s\n", cset); */
6709 /* handle some common aliases */
6712 for (i = 0; p != 0; ){
6715 p = encodings [++i];
6718 if (strcmp (p, codepage) == 0){
6719 *int_code_page = code;
6722 p = encodings [++i];
6725 if (strstr (codepage, "utf_8") != NULL)
6726 *int_code_page |= 0x10000000;
6729 if (want_name && *int_code_page == -1)
6730 return mono_string_new (mono_domain_get (), cset);
6735 ICALL_EXPORT MonoBoolean
6736 ves_icall_System_Environment_get_HasShutdownStarted (void)
6738 if (mono_runtime_is_shutting_down ())
6741 if (mono_domain_is_unloading (mono_domain_get ()))
6749 mono_icall_broadcast_setting_change (void)
6753 #endif /* !HOST_WIN32 */
6756 ves_icall_System_Environment_BroadcastSettingChange (void)
6758 mono_icall_broadcast_setting_change ();
6763 ves_icall_System_Environment_get_TickCount (void)
6765 /* this will overflow after ~24 days */
6766 return (gint32) (mono_msec_boottime () & 0xffffffff);
6770 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6775 #ifndef DISABLE_REMOTING
6776 ICALL_EXPORT MonoBoolean
6777 ves_icall_IsTransparentProxy (MonoObject *proxy)
6782 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6788 ICALL_EXPORT MonoReflectionMethod *
6789 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6790 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6792 MonoReflectionMethod *ret = NULL;
6797 MonoMethod **vtable;
6798 MonoMethod *res = NULL;
6800 MONO_CHECK_ARG_NULL (rtype, NULL);
6801 MONO_CHECK_ARG_NULL (rmethod, NULL);
6803 method = rmethod->method;
6804 klass = mono_class_from_mono_type (rtype->type);
6805 mono_class_init_checked (klass, &error);
6806 if (mono_error_set_pending_exception (&error))
6809 if (MONO_CLASS_IS_INTERFACE (klass))
6812 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6815 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6816 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6822 mono_class_setup_vtable (klass);
6823 vtable = klass->vtable;
6825 if (mono_class_is_interface (method->klass)) {
6826 gboolean variance_used = FALSE;
6827 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6828 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6830 res = vtable [offs + method->slot];
6832 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6835 if (method->slot != -1)
6836 res = vtable [method->slot];
6842 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6843 mono_error_set_pending_exception (&error);
6848 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6854 klass = mono_class_from_mono_type (type->type);
6855 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6856 if (!is_ok (&error)) {
6857 mono_error_set_pending_exception (&error);
6861 mono_vtable_set_is_remote (vtable, enable);
6864 #else /* DISABLE_REMOTING */
6867 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6869 g_assert_not_reached ();
6874 ICALL_EXPORT MonoObject *
6875 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6882 domain = mono_object_domain (type);
6883 klass = mono_class_from_mono_type (type->type);
6884 mono_class_init_checked (klass, &error);
6885 if (mono_error_set_pending_exception (&error))
6888 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6889 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6893 if (klass->rank >= 1) {
6894 g_assert (klass->rank == 1);
6895 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6896 mono_error_set_pending_exception (&error);
6899 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6900 if (!is_ok (&error)) {
6901 mono_error_set_pending_exception (&error);
6904 /* Bypass remoting object creation check */
6905 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6906 mono_error_set_pending_exception (&error);
6912 ICALL_EXPORT MonoStringHandle
6913 ves_icall_System_IO_get_temp_path (MonoError *error)
6915 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6918 #ifndef PLATFORM_NO_DRIVEINFO
6919 ICALL_EXPORT MonoBoolean
6920 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
6921 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
6925 ULARGE_INTEGER wapi_free_bytes_avail;
6926 ULARGE_INTEGER wapi_total_number_of_bytes;
6927 ULARGE_INTEGER wapi_total_number_of_free_bytes;
6929 *error = ERROR_SUCCESS;
6930 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
6931 &wapi_total_number_of_free_bytes);
6934 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
6935 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
6936 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
6938 *free_bytes_avail = 0;
6939 *total_number_of_bytes = 0;
6940 *total_number_of_free_bytes = 0;
6941 *error = GetLastError ();
6947 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6948 static inline guint32
6949 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
6951 return GetDriveType (mono_string_chars (root_path_name));
6953 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6955 ICALL_EXPORT guint32
6956 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
6958 return mono_icall_drive_info_get_drive_type (root_path_name);
6961 #endif /* PLATFORM_NO_DRIVEINFO */
6963 ICALL_EXPORT gpointer
6964 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
6967 gpointer result = mono_compile_method_checked (method, &error);
6968 mono_error_set_pending_exception (&error);
6972 ICALL_EXPORT MonoString *
6973 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6978 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6980 mono_icall_make_platform_path (path);
6982 mcpath = mono_string_new (mono_domain_get (), path);
6988 /* this is an icall */
6990 get_bundled_app_config (void)
6993 const gchar *app_config;
6996 gchar *config_file_name, *config_file_path;
6997 gsize len, config_file_path_length, config_ext_length;
7000 domain = mono_domain_get ();
7001 file = domain->setup->configuration_file;
7002 if (!file || file->length == 0)
7005 // Retrieve config file and remove the extension
7006 config_file_name = mono_string_to_utf8_checked (file, &error);
7007 if (mono_error_set_pending_exception (&error))
7009 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7010 if (!config_file_path)
7011 config_file_path = config_file_name;
7013 config_file_path_length = strlen (config_file_path);
7014 config_ext_length = strlen (".config");
7015 if (config_file_path_length <= config_ext_length)
7018 len = config_file_path_length - config_ext_length;
7019 module = (gchar *)g_malloc0 (len + 1);
7020 memcpy (module, config_file_path, len);
7021 // Get the config file from the module name
7022 app_config = mono_config_string_for_assembly_file (module);
7025 if (config_file_name != config_file_path)
7026 g_free (config_file_name);
7027 g_free (config_file_path);
7032 return mono_string_new (mono_domain_get (), app_config);
7035 static MonoStringHandle
7036 get_bundled_machine_config (MonoError *error)
7038 const gchar *machine_config;
7040 machine_config = mono_get_machine_config ();
7042 if (!machine_config)
7043 return NULL_HANDLE_STRING;
7045 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7048 ICALL_EXPORT MonoStringHandle
7049 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7051 return get_bundled_machine_config (error);
7055 ICALL_EXPORT MonoStringHandle
7056 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7058 return get_bundled_machine_config (error);
7061 ICALL_EXPORT MonoStringHandle
7062 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7064 return get_bundled_machine_config (error);
7068 ICALL_EXPORT MonoString *
7069 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7074 path = g_path_get_dirname (mono_get_config_dir ());
7076 mono_icall_make_platform_path (path);
7078 ipath = mono_string_new (mono_domain_get (), path);
7084 ICALL_EXPORT gboolean
7085 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7087 MonoPEResourceDataEntry *entry;
7090 if (!assembly || !result || !size)
7095 image = assembly->assembly->image;
7096 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7100 *result = mono_image_rva_map (image, entry->rde_data_offset);
7105 *size = entry->rde_size;
7110 ICALL_EXPORT MonoBoolean
7111 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7113 return mono_is_debugger_attached ();
7116 ICALL_EXPORT MonoBoolean
7117 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7119 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7120 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7126 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7128 if (mono_get_runtime_callbacks ()->debug_log)
7129 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7134 mono_icall_write_windows_debug_string (MonoString *message)
7136 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7138 #endif /* !HOST_WIN32 */
7141 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7143 mono_icall_write_windows_debug_string (message);
7146 /* Only used for value types */
7147 ICALL_EXPORT MonoObject *
7148 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7155 domain = mono_object_domain (type);
7156 klass = mono_class_from_mono_type (type->type);
7157 mono_class_init_checked (klass, &error);
7158 if (mono_error_set_pending_exception (&error))
7161 if (mono_class_is_nullable (klass))
7162 /* No arguments -> null */
7165 result = mono_object_new_checked (domain, klass, &error);
7166 mono_error_set_pending_exception (&error);
7170 ICALL_EXPORT MonoReflectionMethod *
7171 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7173 MonoReflectionMethod *ret = NULL;
7176 MonoClass *klass, *parent;
7177 MonoGenericContext *generic_inst = NULL;
7178 MonoMethod *method = m->method;
7179 MonoMethod *result = NULL;
7182 if (method->klass == NULL)
7185 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7186 MONO_CLASS_IS_INTERFACE (method->klass) ||
7187 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7190 slot = mono_method_get_vtable_slot (method);
7194 klass = method->klass;
7195 if (mono_class_is_ginst (klass)) {
7196 generic_inst = mono_class_get_context (klass);
7197 klass = mono_class_get_generic_class (klass)->container_class;
7202 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7203 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7204 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7205 or klass is the generic container class and generic_inst is the instantiation.
7207 when we go to the parent, if the parent is an open constructed type, we need to
7208 replace the type parameters by the definitions from the generic_inst, and then take it
7209 apart again into the klass and the generic_inst.
7211 For cases like this:
7212 class C<T> : B<T, int> {
7213 public override void Foo () { ... }
7215 class B<U,V> : A<HashMap<U,V>> {
7216 public override void Foo () { ... }
7219 public virtual void Foo () { ... }
7222 if at each iteration the parent isn't open, we can skip inflating it. if at some
7223 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7226 MonoGenericContext *parent_inst = NULL;
7227 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7228 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7229 if (!mono_error_ok (&error)) {
7230 mono_error_set_pending_exception (&error);
7234 if (mono_class_is_ginst (parent)) {
7235 parent_inst = mono_class_get_context (parent);
7236 parent = mono_class_get_generic_class (parent)->container_class;
7239 mono_class_setup_vtable (parent);
7240 if (parent->vtable_size <= slot)
7243 generic_inst = parent_inst;
7246 klass = klass->parent;
7249 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7250 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7251 if (!mono_error_ok (&error)) {
7252 mono_error_set_pending_exception (&error);
7256 generic_inst = NULL;
7258 if (mono_class_is_ginst (klass)) {
7259 generic_inst = mono_class_get_context (klass);
7260 klass = mono_class_get_generic_class (klass)->container_class;
7266 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7267 if (!mono_error_ok (&error)) {
7268 mono_error_set_pending_exception (&error);
7273 if (klass == method->klass)
7276 /*This is possible if definition == FALSE.
7277 * Do it here to be really sure we don't read invalid memory.
7279 if (slot >= klass->vtable_size)
7282 mono_class_setup_vtable (klass);
7284 result = klass->vtable [slot];
7285 if (result == NULL) {
7286 /* It is an abstract method */
7287 gboolean found = FALSE;
7288 gpointer iter = NULL;
7289 while ((result = mono_class_get_methods (klass, &iter))) {
7290 if (result->slot == slot) {
7295 /* found might be FALSE if we looked in an abstract class
7296 * that doesn't override an abstract method of its
7298 * abstract class Base {
7299 * public abstract void Foo ();
7301 * abstract class Derived : Base { }
7302 * class Child : Derived {
7303 * public override void Foo () { }
7306 * if m was Child.Foo and we ask for the base method,
7307 * then we get here with klass == Derived and found == FALSE
7309 /* but it shouldn't be the case that if we're looking
7310 * for the definition and didn't find a result; the
7311 * loop above should've taken us as far as we could
7313 g_assert (!(definition && !found));
7318 g_assert (result != NULL);
7320 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7321 mono_error_set_pending_exception (&error);
7325 ICALL_EXPORT MonoString*
7326 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7328 MonoMethod *method = m->method;
7330 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7335 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7337 iter->sig = *(MonoMethodSignature**)argsp;
7339 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7340 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7343 /* FIXME: it's not documented what start is exactly... */
7347 iter->args = argsp + sizeof (gpointer);
7349 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7351 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7354 ICALL_EXPORT MonoTypedRef
7355 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7357 guint32 i, arg_size;
7361 i = iter->sig->sentinelpos + iter->next_arg;
7363 g_assert (i < iter->sig->param_count);
7365 res.type = iter->sig->params [i];
7366 res.klass = mono_class_from_mono_type (res.type);
7367 arg_size = mono_type_stack_size (res.type, &align);
7368 #if defined(__arm__) || defined(__mips__)
7369 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7371 res.value = iter->args;
7372 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7373 /* Values are stored as 8 byte register sized objects, but 'value'
7374 * is dereferenced as a pointer in other routines.
7376 res.value = (char*)res.value + 4;
7378 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7379 if (arg_size <= sizeof (gpointer)) {
7381 int padding = arg_size - mono_type_size (res.type, &dummy);
7382 res.value = (guint8*)res.value + padding;
7385 iter->args = (char*)iter->args + arg_size;
7388 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7393 ICALL_EXPORT MonoTypedRef
7394 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7396 guint32 i, arg_size;
7400 i = iter->sig->sentinelpos + iter->next_arg;
7402 g_assert (i < iter->sig->param_count);
7404 while (i < iter->sig->param_count) {
7405 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7407 res.type = iter->sig->params [i];
7408 res.klass = mono_class_from_mono_type (res.type);
7409 /* FIXME: endianess issue... */
7410 arg_size = mono_type_stack_size (res.type, &align);
7411 #if defined(__arm__) || defined(__mips__)
7412 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7414 res.value = iter->args;
7415 iter->args = (char*)iter->args + arg_size;
7417 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7420 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7428 ICALL_EXPORT MonoType*
7429 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7433 i = iter->sig->sentinelpos + iter->next_arg;
7435 g_assert (i < iter->sig->param_count);
7437 return iter->sig->params [i];
7440 ICALL_EXPORT MonoObject*
7441 mono_TypedReference_ToObject (MonoTypedRef* tref)
7444 MonoObject *result = NULL;
7445 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7446 MonoObject** objp = (MonoObject **)tref->value;
7450 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7451 mono_error_set_pending_exception (&error);
7455 ICALL_EXPORT MonoTypedRef
7456 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7459 MonoReflectionField *f;
7461 MonoType *ftype = NULL;
7465 memset (&res, 0, sizeof (res));
7468 g_assert (mono_array_length (fields) > 0);
7470 klass = target->vtable->klass;
7472 for (i = 0; i < mono_array_length (fields); ++i) {
7473 f = mono_array_get (fields, MonoReflectionField*, i);
7475 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7478 if (f->field->parent != klass) {
7479 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7483 p = (guint8*)target + f->field->offset;
7485 p += f->field->offset - sizeof (MonoObject);
7486 klass = mono_class_from_mono_type (f->field->type);
7487 ftype = f->field->type;
7491 res.klass = mono_class_from_mono_type (ftype);
7498 prelink_method (MonoMethod *method, MonoError *error)
7500 const char *exc_class, *exc_arg;
7502 mono_error_init (error);
7503 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7505 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7507 mono_error_set_exception_instance (error,
7508 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7511 /* create the wrapper, too? */
7515 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7519 prelink_method (method->method, &error);
7520 mono_error_set_pending_exception (&error);
7524 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7527 MonoClass *klass = mono_class_from_mono_type (type->type);
7529 gpointer iter = NULL;
7531 mono_class_init_checked (klass, &error);
7532 if (mono_error_set_pending_exception (&error))
7535 while ((m = mono_class_get_methods (klass, &iter))) {
7536 prelink_method (m, &error);
7537 if (mono_error_set_pending_exception (&error))
7542 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7544 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7545 gint32 const **exponents,
7546 gunichar2 const **digitLowerTable,
7547 gunichar2 const **digitUpperTable,
7548 gint64 const **tenPowersList,
7549 gint32 const **decHexDigits)
7551 *mantissas = Formatter_MantissaBitsTable;
7552 *exponents = Formatter_TensExponentTable;
7553 *digitLowerTable = Formatter_DigitLowerTable;
7554 *digitUpperTable = Formatter_DigitUpperTable;
7555 *tenPowersList = Formatter_TenPowersList;
7556 *decHexDigits = Formatter_DecHexDigits;
7560 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7561 * and avoid useless allocations.
7564 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7566 MonoReflectionType *rt;
7570 mono_error_init (error);
7571 for (i = 0; i < type->num_mods; ++i) {
7572 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7577 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7578 return_val_if_nok (error, NULL);
7580 for (i = 0; i < type->num_mods; ++i) {
7581 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7582 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7583 return_val_if_nok (error, NULL);
7585 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7586 return_val_if_nok (error, NULL);
7588 mono_array_setref (res, count, rt);
7595 ICALL_EXPORT MonoArray*
7596 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7599 MonoType *type = param->ClassImpl->type;
7600 MonoClass *member_class = mono_object_class (param->MemberImpl);
7601 MonoMethod *method = NULL;
7604 MonoMethodSignature *sig;
7607 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7608 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7609 method = rmethod->method;
7610 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7611 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7612 if (!(method = prop->property->get))
7613 method = prop->property->set;
7616 char *type_name = mono_type_get_full_name (member_class);
7617 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7618 MonoException *ex = mono_get_exception_not_supported (msg);
7621 mono_set_pending_exception (ex);
7625 image = method->klass->image;
7626 pos = param->PositionImpl;
7627 sig = mono_method_signature (method);
7631 type = sig->params [pos];
7633 res = type_array_from_modifiers (image, type, optional, &error);
7634 mono_error_set_pending_exception (&error);
7639 get_property_type (MonoProperty *prop)
7641 MonoMethodSignature *sig;
7643 sig = mono_method_signature (prop->get);
7645 } else if (prop->set) {
7646 sig = mono_method_signature (prop->set);
7647 return sig->params [sig->param_count - 1];
7652 ICALL_EXPORT MonoArray*
7653 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7656 MonoType *type = get_property_type (property->property);
7657 MonoImage *image = property->klass->image;
7662 res = type_array_from_modifiers (image, type, optional, &error);
7663 mono_error_set_pending_exception (&error);
7668 *Construct a MonoType suited to be used to decode a constant blob object.
7670 * @type is the target type which will be constructed
7671 * @blob_type is the blob type, for example, that comes from the constant table
7672 * @real_type is the expected constructed type.
7675 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7677 type->type = blob_type;
7678 type->data.klass = NULL;
7679 if (blob_type == MONO_TYPE_CLASS)
7680 type->data.klass = mono_defaults.object_class;
7681 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7682 /* For enums, we need to use the base type */
7683 type->type = MONO_TYPE_VALUETYPE;
7684 type->data.klass = mono_class_from_mono_type (real_type);
7686 type->data.klass = mono_class_from_mono_type (real_type);
7689 ICALL_EXPORT MonoObject*
7690 property_info_get_default_value (MonoReflectionProperty *property)
7694 MonoProperty *prop = property->property;
7695 MonoType *type = get_property_type (prop);
7696 MonoDomain *domain = mono_object_domain (property);
7697 MonoTypeEnum def_type;
7698 const char *def_value;
7701 mono_class_init (prop->parent);
7703 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7704 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7708 def_value = mono_class_get_property_default_value (prop, &def_type);
7710 mono_type_from_blob_type (&blob_type, def_type, type);
7711 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7713 mono_error_set_pending_exception (&error);
7717 ICALL_EXPORT MonoBoolean
7718 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7721 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7722 MonoCustomAttrInfo *cinfo;
7725 mono_class_init_checked (attr_class, &error);
7726 if (mono_error_set_pending_exception (&error))
7729 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7730 if (!is_ok (&error)) {
7731 mono_error_set_pending_exception (&error);
7736 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7738 mono_custom_attrs_free (cinfo);
7742 ICALL_EXPORT MonoArray*
7743 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7745 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7750 mono_class_init_checked (attr_class, &error);
7751 if (mono_error_set_pending_exception (&error))
7755 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7756 if (!mono_error_ok (&error)) {
7757 mono_error_set_pending_exception (&error);
7764 ICALL_EXPORT MonoArray*
7765 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7769 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7770 mono_error_set_pending_exception (&error);
7775 ICALL_EXPORT MonoStringHandle
7776 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7779 MonoStringHandle display_name;
7781 mono_error_init (error);
7782 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7783 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7785 return display_name;
7788 ICALL_EXPORT MonoString*
7789 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7792 MonoString *message;
7796 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7797 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7800 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7802 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7803 if (mono_error_set_pending_exception (&error))
7811 static inline gint32
7812 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7814 return WAIT_TIMEOUT;
7816 #endif /* !HOST_WIN32 */
7819 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7821 return mono_icall_wait_for_input_idle (handle, milliseconds);
7825 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7827 return mono_process_current_pid ();
7830 ICALL_EXPORT MonoBoolean
7831 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7843 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7845 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7849 ICALL_EXPORT MonoObject*
7850 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7852 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7857 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7859 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7863 ICALL_EXPORT MonoObject*
7864 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7866 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7870 ICALL_EXPORT MonoBoolean
7871 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7873 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7878 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7880 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7884 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7886 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7891 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7893 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7897 ICALL_EXPORT mono_unichar2*
7898 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7900 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7907 #ifndef DISABLE_ICALL_TABLES
7909 #define ICALL_TYPE(id,name,first)
7910 #define ICALL(id,name,func) Icall_ ## id,
7911 #define HANDLES(inner) inner
7914 #include "metadata/icall-def.h"
7920 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7921 #define ICALL(id,name,func)
7923 #define HANDLES(inner) inner
7925 #include "metadata/icall-def.h"
7931 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7932 #define ICALL(id,name,func)
7934 #define HANDLES(inner) inner
7936 guint16 first_icall;
7939 static const IcallTypeDesc
7940 icall_type_descs [] = {
7941 #include "metadata/icall-def.h"
7945 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7948 #define HANDLES(inner) inner
7950 #define ICALL_TYPE(id,name,first)
7953 #ifdef HAVE_ARRAY_ELEM_INIT
7954 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7955 #define MSGSTRFIELD1(line) str##line
7957 static const struct msgstrtn_t {
7958 #define ICALL(id,name,func)
7960 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7961 #include "metadata/icall-def.h"
7963 } icall_type_names_str = {
7964 #define ICALL_TYPE(id,name,first) (name),
7965 #include "metadata/icall-def.h"
7968 static const guint16 icall_type_names_idx [] = {
7969 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7970 #include "metadata/icall-def.h"
7973 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7975 static const struct msgstr_t {
7977 #define ICALL_TYPE(id,name,first)
7978 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7979 #include "metadata/icall-def.h"
7981 } icall_names_str = {
7982 #define ICALL(id,name,func) (name),
7983 #include "metadata/icall-def.h"
7986 static const guint16 icall_names_idx [] = {
7987 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7988 #include "metadata/icall-def.h"
7991 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7997 #define ICALL_TYPE(id,name,first) name,
7998 #define ICALL(id,name,func)
7999 static const char* const
8000 icall_type_names [] = {
8001 #include "metadata/icall-def.h"
8005 #define icall_type_name_get(id) (icall_type_names [(id)])
8009 #define ICALL_TYPE(id,name,first)
8010 #define ICALL(id,name,func) name,
8011 static const char* const
8013 #include "metadata/icall-def.h"
8016 #define icall_name_get(id) icall_names [(id)]
8018 #endif /* !HAVE_ARRAY_ELEM_INIT */
8021 #define HANDLES(inner) inner
8024 #define ICALL_TYPE(id,name,first)
8025 #define ICALL(id,name,func) func,
8026 static const gconstpointer
8027 icall_functions [] = {
8028 #include "metadata/icall-def.h"
8032 #ifdef ENABLE_ICALL_SYMBOL_MAP
8034 #define HANDLES(inner) inner
8037 #define ICALL_TYPE(id,name,first)
8038 #define ICALL(id,name,func) #func,
8039 static const gconstpointer
8040 icall_symbols [] = {
8041 #include "metadata/icall-def.h"
8048 #define ICALL_TYPE(id,name,first)
8049 #define ICALL(id,name,func) 0,
8051 #define HANDLES(inner) 1,
8053 icall_uses_handles [] = {
8054 #include "metadata/icall-def.h"
8059 #endif /* DISABLE_ICALL_TABLES */
8061 static mono_mutex_t icall_mutex;
8062 static GHashTable *icall_hash = NULL;
8063 static GHashTable *jit_icall_hash_name = NULL;
8064 static GHashTable *jit_icall_hash_addr = NULL;
8067 mono_icall_init (void)
8069 #ifndef DISABLE_ICALL_TABLES
8072 /* check that tables are sorted: disable in release */
8075 const char *prev_class = NULL;
8076 const char *prev_method;
8078 for (i = 0; i < Icall_type_num; ++i) {
8079 const IcallTypeDesc *desc;
8082 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8083 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8084 prev_class = icall_type_name_get (i);
8085 desc = &icall_type_descs [i];
8086 num_icalls = icall_desc_num_icalls (desc);
8087 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8088 for (j = 0; j < num_icalls; ++j) {
8089 const char *methodn = icall_name_get (desc->first_icall + j);
8090 if (prev_method && strcmp (prev_method, methodn) >= 0)
8091 g_print ("method %s should come before method %s\n", methodn, prev_method);
8092 prev_method = methodn;
8098 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8099 mono_os_mutex_init (&icall_mutex);
8103 mono_icall_lock (void)
8105 mono_locks_os_acquire (&icall_mutex, IcallLock);
8109 mono_icall_unlock (void)
8111 mono_locks_os_release (&icall_mutex, IcallLock);
8115 mono_icall_cleanup (void)
8117 g_hash_table_destroy (icall_hash);
8118 g_hash_table_destroy (jit_icall_hash_name);
8119 g_hash_table_destroy (jit_icall_hash_addr);
8120 mono_os_mutex_destroy (&icall_mutex);
8124 * mono_add_internal_call:
8125 * @name: method specification to surface to the managed world
8126 * @method: pointer to a C method to invoke when the method is called
8128 * This method surfaces the C function pointed by @method as a method
8129 * that has been surfaced in managed code with the method specified in
8130 * @name as an internal call.
8132 * Internal calls are surfaced to all app domains loaded and they are
8133 * accessibly by a type with the specified name.
8135 * You must provide a fully qualified type name, that is namespaces
8136 * and type name, followed by a colon and the method name, with an
8137 * optional signature to bind.
8139 * For example, the following are all valid declarations:
8141 * "MyApp.Services.ScriptService:Accelerate"
8142 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8144 * You use method parameters in cases where there might be more than
8145 * one surface method to managed code. That way you can register different
8146 * internal calls for different method overloads.
8148 * The internal calls are invoked with no marshalling. This means that .NET
8149 * types like System.String are exposed as `MonoString *` parameters. This is
8150 * different than the way that strings are surfaced in P/Invoke.
8152 * For more information on how the parameters are marshalled, see the
8153 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8156 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8157 * reference for more information on the format of method descriptions.
8160 mono_add_internal_call (const char *name, gconstpointer method)
8164 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8166 mono_icall_unlock ();
8169 #ifndef DISABLE_ICALL_TABLES
8171 #ifdef HAVE_ARRAY_ELEM_INIT
8173 compare_method_imap (const void *key, const void *elem)
8175 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8176 return strcmp (key, method_name);
8180 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8182 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);
8185 return (nameslot - &icall_names_idx [0]);
8189 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8191 gsize slotnum = find_slot_icall (imap, name);
8194 return (gboolean)icall_uses_handles [slotnum];
8198 find_method_icall (const IcallTypeDesc *imap, const char *name)
8200 gsize slotnum = find_slot_icall (imap, name);
8203 return (gpointer)icall_functions [slotnum];
8207 compare_class_imap (const void *key, const void *elem)
8209 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8210 return strcmp (key, class_name);
8213 static const IcallTypeDesc*
8214 find_class_icalls (const char *name)
8216 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);
8219 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8222 #else /* HAVE_ARRAY_ELEM_INIT */
8225 compare_method_imap (const void *key, const void *elem)
8227 const char** method_name = (const char**)elem;
8228 return strcmp (key, *method_name);
8232 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8234 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8237 return nameslot - icall_names;
8241 find_method_icall (const IcallTypeDesc *imap, const char *name)
8243 gsize slotnum = find_slot_icall (imap, name);
8246 return (gpointer)icall_functions [slotnum];
8250 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8252 gsize slotnum = find_slot_icall (imap, name);
8255 return (gboolean)icall_uses_handles [slotnum];
8259 compare_class_imap (const void *key, const void *elem)
8261 const char** class_name = (const char**)elem;
8262 return strcmp (key, *class_name);
8265 static const IcallTypeDesc*
8266 find_class_icalls (const char *name)
8268 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8271 return &icall_type_descs [nameslot - icall_type_names];
8274 #endif /* HAVE_ARRAY_ELEM_INIT */
8276 #endif /* DISABLE_ICALL_TABLES */
8279 * we should probably export this as an helper (handle nested types).
8280 * Returns the number of chars written in buf.
8283 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8285 int nspacelen, cnamelen;
8286 nspacelen = strlen (klass->name_space);
8287 cnamelen = strlen (klass->name);
8288 if (nspacelen + cnamelen + 2 > bufsize)
8291 memcpy (buf, klass->name_space, nspacelen);
8292 buf [nspacelen ++] = '.';
8294 memcpy (buf + nspacelen, klass->name, cnamelen);
8295 buf [nspacelen + cnamelen] = 0;
8296 return nspacelen + cnamelen;
8299 #ifdef DISABLE_ICALL_TABLES
8301 no_icall_table (void)
8303 g_assert_not_reached ();
8308 * mono_lookup_internal_call_full:
8309 * @method: the method to look up
8310 * @uses_handles: out argument if method needs handles around managed objects.
8312 * Returns a pointer to the icall code for the given method. If
8313 * uses_handles is not NULL, it will be set to TRUE if the method
8314 * needs managed objects wrapped using the infrastructure in handle.h
8316 * If the method is not found, warns and returns NULL.
8319 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8324 int typelen = 0, mlen, siglen;
8326 #ifndef DISABLE_ICALL_TABLES
8327 const IcallTypeDesc *imap = NULL;
8330 g_assert (method != NULL);
8332 if (method->is_inflated)
8333 method = ((MonoMethodInflated *) method)->declaring;
8335 if (method->klass->nested_in) {
8336 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8340 mname [pos++] = '/';
8343 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8349 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8354 #ifndef DISABLE_ICALL_TABLES
8355 imap = find_class_icalls (mname);
8358 mname [typelen] = ':';
8359 mname [typelen + 1] = ':';
8361 mlen = strlen (method->name);
8362 memcpy (mname + typelen + 2, method->name, mlen);
8363 sigstart = mname + typelen + 2 + mlen;
8366 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8367 siglen = strlen (tmpsig);
8368 if (typelen + mlen + siglen + 6 > sizeof (mname))
8371 memcpy (sigstart + 1, tmpsig, siglen);
8372 sigstart [siglen + 1] = ')';
8373 sigstart [siglen + 2] = 0;
8378 res = g_hash_table_lookup (icall_hash, mname);
8381 *uses_handles = FALSE;
8382 mono_icall_unlock ();;
8385 /* try without signature */
8387 res = g_hash_table_lookup (icall_hash, mname);
8390 *uses_handles = FALSE;
8391 mono_icall_unlock ();
8395 #ifdef DISABLE_ICALL_TABLES
8396 mono_icall_unlock ();
8397 /* Fail only when the result is actually used */
8398 /* mono_marshal_get_native_wrapper () depends on this */
8399 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8400 return ves_icall_System_String_ctor_RedirectToCreateString;
8402 return no_icall_table;
8404 /* it wasn't found in the static call tables */
8407 *uses_handles = FALSE;
8408 mono_icall_unlock ();
8411 res = find_method_icall (imap, sigstart - mlen);
8414 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8415 mono_icall_unlock ();
8418 /* try _with_ signature */
8420 res = find_method_icall (imap, sigstart - mlen);
8423 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8424 mono_icall_unlock ();
8428 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8429 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8430 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8431 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8432 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");
8433 g_print ("If you see other errors or faults after this message they are probably related\n");
8434 g_print ("and you need to fix your mono install first.\n");
8436 mono_icall_unlock ();
8443 mono_lookup_internal_call (MonoMethod *method)
8445 return mono_lookup_internal_call_full (method, NULL);
8448 #ifdef ENABLE_ICALL_SYMBOL_MAP
8450 func_cmp (gconstpointer key, gconstpointer p)
8452 return (gsize)key - (gsize)*(gsize*)p;
8457 * mono_lookup_icall_symbol:
8459 * Given the icall METHOD, returns its C symbol.
8462 mono_lookup_icall_symbol (MonoMethod *m)
8464 #ifdef DISABLE_ICALL_TABLES
8465 g_assert_not_reached ();
8468 #ifdef ENABLE_ICALL_SYMBOL_MAP
8472 static gconstpointer *functions_sorted;
8473 static const char**symbols_sorted;
8474 static gboolean inited;
8479 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8480 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8481 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8482 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8483 /* Bubble sort the two arrays */
8487 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8488 if (functions_sorted [i] > functions_sorted [i + 1]) {
8491 tmp = functions_sorted [i];
8492 functions_sorted [i] = functions_sorted [i + 1];
8493 functions_sorted [i + 1] = tmp;
8494 tmp = symbols_sorted [i];
8495 symbols_sorted [i] = symbols_sorted [i + 1];
8496 symbols_sorted [i + 1] = tmp;
8503 func = mono_lookup_internal_call (m);
8506 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8510 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8512 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8513 g_assert_not_reached ();
8520 type_from_typename (char *type_name)
8522 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8524 if (!strcmp (type_name, "int"))
8525 klass = mono_defaults.int_class;
8526 else if (!strcmp (type_name, "ptr"))
8527 klass = mono_defaults.int_class;
8528 else if (!strcmp (type_name, "void"))
8529 klass = mono_defaults.void_class;
8530 else if (!strcmp (type_name, "int32"))
8531 klass = mono_defaults.int32_class;
8532 else if (!strcmp (type_name, "uint32"))
8533 klass = mono_defaults.uint32_class;
8534 else if (!strcmp (type_name, "int8"))
8535 klass = mono_defaults.sbyte_class;
8536 else if (!strcmp (type_name, "uint8"))
8537 klass = mono_defaults.byte_class;
8538 else if (!strcmp (type_name, "int16"))
8539 klass = mono_defaults.int16_class;
8540 else if (!strcmp (type_name, "uint16"))
8541 klass = mono_defaults.uint16_class;
8542 else if (!strcmp (type_name, "long"))
8543 klass = mono_defaults.int64_class;
8544 else if (!strcmp (type_name, "ulong"))
8545 klass = mono_defaults.uint64_class;
8546 else if (!strcmp (type_name, "float"))
8547 klass = mono_defaults.single_class;
8548 else if (!strcmp (type_name, "double"))
8549 klass = mono_defaults.double_class;
8550 else if (!strcmp (type_name, "object"))
8551 klass = mono_defaults.object_class;
8552 else if (!strcmp (type_name, "obj"))
8553 klass = mono_defaults.object_class;
8554 else if (!strcmp (type_name, "string"))
8555 klass = mono_defaults.string_class;
8556 else if (!strcmp (type_name, "bool"))
8557 klass = mono_defaults.boolean_class;
8558 else if (!strcmp (type_name, "boolean"))
8559 klass = mono_defaults.boolean_class;
8561 g_error ("%s", type_name);
8562 g_assert_not_reached ();
8564 return &klass->byval_arg;
8568 * LOCKING: Take the corlib image lock.
8570 MonoMethodSignature*
8571 mono_create_icall_signature (const char *sigstr)
8576 MonoMethodSignature *res, *res2;
8577 MonoImage *corlib = mono_defaults.corlib;
8579 mono_image_lock (corlib);
8580 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8581 mono_image_unlock (corlib);
8586 parts = g_strsplit (sigstr, " ", 256);
8595 res = mono_metadata_signature_alloc (corlib, len - 1);
8600 * Under windows, the default pinvoke calling convention is STDCALL but
8603 res->call_convention = MONO_CALL_C;
8606 res->ret = type_from_typename (parts [0]);
8607 for (i = 1; i < len; ++i) {
8608 res->params [i - 1] = type_from_typename (parts [i]);
8613 mono_image_lock (corlib);
8614 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8616 res = res2; /*Value is allocated in the image pool*/
8618 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8619 mono_image_unlock (corlib);
8625 mono_find_jit_icall_by_name (const char *name)
8627 MonoJitICallInfo *info;
8628 g_assert (jit_icall_hash_name);
8631 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8632 mono_icall_unlock ();
8637 mono_find_jit_icall_by_addr (gconstpointer addr)
8639 MonoJitICallInfo *info;
8640 g_assert (jit_icall_hash_addr);
8643 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8644 mono_icall_unlock ();
8650 * mono_get_jit_icall_info:
8652 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8653 * caller should access it while holding the icall lock.
8656 mono_get_jit_icall_info (void)
8658 return jit_icall_hash_name;
8662 * mono_lookup_jit_icall_symbol:
8664 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8667 mono_lookup_jit_icall_symbol (const char *name)
8669 MonoJitICallInfo *info;
8670 const char *res = NULL;
8673 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8675 res = info->c_symbol;
8676 mono_icall_unlock ();
8681 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8684 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8685 mono_icall_unlock ();
8689 * 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
8690 * icalls without wrappers in some cases.
8693 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8695 MonoJitICallInfo *info;
8702 if (!jit_icall_hash_name) {
8703 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8704 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8707 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8708 g_warning ("jit icall already defined \"%s\"\n", name);
8709 g_assert_not_reached ();
8712 info = g_new0 (MonoJitICallInfo, 1);
8717 info->c_symbol = c_symbol;
8718 info->no_raise = no_raise;
8721 info->wrapper = func;
8723 info->wrapper = NULL;
8726 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8727 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8729 mono_icall_unlock ();
8734 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8736 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);