5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool.h>
40 #include <mono/metadata/threadpool-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/metadata-internals.h>
56 #include <mono/metadata/class-internals.h>
57 #include <mono/metadata/reflection-internals.h>
58 #include <mono/metadata/marshal.h>
59 #include <mono/metadata/gc-internals.h>
60 #include <mono/metadata/mono-gc.h>
61 #include <mono/metadata/rand.h>
62 #include <mono/metadata/sysmath.h>
63 #include <mono/metadata/appdomain-icalls.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssemblyHandle ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
120 static MonoArrayHandle
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 MonoReflectionTypeHandle
1216 ves_icall_System_Object_GetType (MonoObjectHandle obj, MonoError *error)
1218 mono_error_init (error);
1219 MonoDomain *domain = MONO_HANDLE_DOMAIN (obj);
1220 MonoClass *klass = mono_handle_class (obj);
1221 #ifndef DISABLE_REMOTING
1222 if (klass == mono_defaults.transparent_proxy_class) {
1223 MonoTransparentProxyHandle proxy_obj = MONO_HANDLE_CAST (MonoTransparentProxy, obj);
1224 MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (proxy_obj, remote_class);
1225 MonoType *proxy_type = &remote_class->proxy_class->byval_arg;
1226 return mono_type_get_object_handle (domain, proxy_type, error);
1229 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
1233 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1235 MonoMethod **dest = (MonoMethod **)data;
1237 /* skip unmanaged frames */
1242 if (!strcmp (m->klass->name_space, "System.Reflection"))
1251 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1253 MonoMethod **dest = (MonoMethod **)data;
1255 /* skip unmanaged frames */
1259 if (m->wrapper_type != MONO_WRAPPER_NONE)
1267 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1278 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1280 MonoMethod **dest = (MonoMethod **)data;
1282 /* skip unmanaged frames */
1286 if (m->wrapper_type != MONO_WRAPPER_NONE)
1294 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1295 || (!strcmp (m->klass->name_space, "System"))))
1305 static MonoReflectionTypeHandle
1306 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1308 MonoMethod *m, *dest;
1310 MonoType *type = NULL;
1311 MonoAssembly *assembly = NULL;
1312 gboolean type_resolve = FALSE;
1313 MonoImage *rootimage = NULL;
1315 mono_error_init (error);
1318 * We must compute the calling assembly as type loading must happen under a metadata context.
1319 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1320 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1322 m = mono_method_get_last_managed ();
1324 if (m && m->klass->image != mono_defaults.corlib) {
1325 /* Happens with inlining */
1327 /* Ugly hack: type_from_parsed_name is called from
1328 * System.Type.internal_from_name, which is called most
1329 * directly from System.Type.GetType(string,bool,bool) but
1330 * also indirectly from places such as
1331 * System.Type.GetType(string,func,func) (via
1332 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1333 * so we need to skip over all of those to find the true caller.
1335 * It would be nice if we had stack marks.
1337 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1343 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1344 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1345 * to crash. This only seems to happen in some strange remoting
1346 * scenarios and I was unable to figure out what's happening there.
1347 * Dec 10, 2005 - Martin.
1351 assembly = dest->klass->image->assembly;
1352 type_resolve = TRUE;
1353 rootimage = assembly->image;
1355 g_warning (G_STRLOC);
1357 *caller_assembly = assembly;
1359 if (info->assembly.name)
1360 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1363 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1364 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1370 // Say we're looking for System.Generic.Dict<int, Local>
1371 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1372 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1373 // is messed up when we go to construct the Local as the type arg...
1375 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1376 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1377 if (!info->assembly.name && !type) {
1379 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1383 if (assembly && !type && type_resolve) {
1384 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1385 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1393 return mono_type_get_object_handle (mono_domain_get (), type, error);
1395 return MONO_HANDLE_NEW (MonoReflectionType, NULL);
1398 ICALL_EXPORT MonoReflectionTypeHandle
1399 ves_icall_System_Type_internal_from_name (MonoStringHandle name,
1400 MonoBoolean throwOnError,
1401 MonoBoolean ignoreCase,
1404 mono_error_init (error);
1405 MonoTypeNameParse info;
1407 MonoAssembly *caller_assembly;
1408 MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1410 char *str = mono_string_handle_to_utf8 (name, error);
1414 parsedOk = mono_reflection_parse_type (str, &info);
1416 /* mono_reflection_parse_type() mangles the string */
1418 mono_reflection_free_type_info (&info);
1420 mono_error_set_argument (error, "typeName", "failed parse: %s", str);
1424 MONO_HANDLE_ASSIGN (type, type_from_parsed_name (&info, ignoreCase, &caller_assembly, error));
1426 if (!is_ok (error)) {
1427 mono_reflection_free_type_info (&info);
1431 if (MONO_HANDLE_IS_NULL (type)) {
1433 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1435 if (info.assembly.name)
1436 aname = mono_stringify_assembly_name (&info.assembly);
1437 else if (caller_assembly)
1438 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1440 aname = g_strdup ("");
1441 mono_error_set_type_load_name (error, tname, aname, "");
1443 mono_reflection_free_type_info (&info);
1449 if (!is_ok (error)) {
1451 mono_error_cleanup (error);
1452 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
1459 ICALL_EXPORT MonoReflectionTypeHandle
1460 ves_icall_System_Type_internal_from_handle (MonoType *handle, MonoError *error)
1462 mono_error_init (error);
1463 MonoDomain *domain = mono_domain_get ();
1465 return mono_type_get_object_handle (domain, handle, error);
1468 ICALL_EXPORT MonoType*
1469 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1471 return mono_class_get_type (klass);
1475 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1477 g_ptr_array_free (ptr_array, TRUE);
1481 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1487 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1490 char *res = mono_string_to_utf8_checked (s, &error);
1491 mono_error_set_pending_exception (&error);
1495 /* System.TypeCode */
1514 TYPECODE_STRING = 18
1517 ICALL_EXPORT guint32
1518 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1520 int t = type->type->type;
1522 if (type->type->byref)
1523 return TYPECODE_OBJECT;
1527 case MONO_TYPE_VOID:
1528 return TYPECODE_OBJECT;
1529 case MONO_TYPE_BOOLEAN:
1530 return TYPECODE_BOOLEAN;
1532 return TYPECODE_BYTE;
1534 return TYPECODE_SBYTE;
1536 return TYPECODE_UINT16;
1538 return TYPECODE_INT16;
1539 case MONO_TYPE_CHAR:
1540 return TYPECODE_CHAR;
1544 return TYPECODE_OBJECT;
1546 return TYPECODE_UINT32;
1548 return TYPECODE_INT32;
1550 return TYPECODE_UINT64;
1552 return TYPECODE_INT64;
1554 return TYPECODE_SINGLE;
1556 return TYPECODE_DOUBLE;
1557 case MONO_TYPE_VALUETYPE: {
1558 MonoClass *klass = type->type->data.klass;
1560 if (klass->enumtype) {
1561 t = mono_class_enum_basetype (klass)->type;
1563 } else if (mono_is_corlib_image (klass->image)) {
1564 if (strcmp (klass->name_space, "System") == 0) {
1565 if (strcmp (klass->name, "Decimal") == 0)
1566 return TYPECODE_DECIMAL;
1567 else if (strcmp (klass->name, "DateTime") == 0)
1568 return TYPECODE_DATETIME;
1571 return TYPECODE_OBJECT;
1573 case MONO_TYPE_STRING:
1574 return TYPECODE_STRING;
1575 case MONO_TYPE_SZARRAY:
1576 case MONO_TYPE_ARRAY:
1577 case MONO_TYPE_OBJECT:
1579 case MONO_TYPE_MVAR:
1580 case MONO_TYPE_TYPEDBYREF:
1581 return TYPECODE_OBJECT;
1582 case MONO_TYPE_CLASS:
1584 MonoClass *klass = type->type->data.klass;
1585 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1586 if (strcmp (klass->name, "DBNull") == 0)
1587 return TYPECODE_DBNULL;
1590 return TYPECODE_OBJECT;
1591 case MONO_TYPE_GENERICINST:
1592 return TYPECODE_OBJECT;
1594 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1600 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1602 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1603 return mono_class_enum_basetype (type->data.klass);
1604 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1605 return mono_class_enum_basetype (type->data.generic_class->container_class);
1609 ICALL_EXPORT guint32
1610 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_c, MonoError *error)
1612 mono_error_init (error);
1614 g_assert (!MONO_HANDLE_IS_NULL (ref_type));
1616 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1617 MonoClass *klass = mono_class_from_mono_type (type);
1618 MonoType *ctype = MONO_HANDLE_GETVAL (ref_c, type);
1619 MonoClass *klassc = mono_class_from_mono_type (ctype);
1621 if (type->byref ^ ctype->byref)
1625 MonoType *t = mono_type_get_underlying_type_ignore_byref (type);
1626 MonoType *ot = mono_type_get_underlying_type_ignore_byref (ctype);
1628 klass = mono_class_from_mono_type (t);
1629 klassc = mono_class_from_mono_type (ot);
1631 if (mono_type_is_primitive (t)) {
1632 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1633 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1634 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1635 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1636 return t->type == ot->type;
1638 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1641 if (klass->valuetype)
1642 return klass == klassc;
1643 return klass->valuetype == klassc->valuetype;
1646 return mono_class_is_assignable_from (klass, klassc);
1649 ICALL_EXPORT guint32
1650 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionTypeHandle ref_type, MonoObjectHandle obj, MonoError *error)
1652 mono_error_init (error);
1653 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1654 MonoClass *klass = mono_class_from_mono_type (type);
1655 mono_class_init_checked (klass, error);
1656 return_val_if_nok (error, FALSE);
1657 MonoObjectHandle inst = mono_object_handle_isinst (obj, klass, error);
1658 return_val_if_nok (error, FALSE);
1659 return !MONO_HANDLE_IS_NULL (inst);
1662 ICALL_EXPORT guint32
1663 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionTypeHandle ref_type, MonoError *error)
1665 mono_error_init (error);
1666 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1667 MonoClass *klass = mono_class_from_mono_type (type);
1668 return mono_class_get_flags (klass);
1671 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1672 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h, MonoError *error)
1674 mono_error_init (error);
1675 MonoDomain *domain = MONO_HANDLE_DOMAIN (field_h);
1676 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1677 MonoClass *klass = field->parent;
1679 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1680 if (mono_class_is_gtd (klass) ||
1681 (gklass && gklass->context.class_inst->is_open))
1682 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1684 MonoType *ftype = mono_field_get_type (field);
1685 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1686 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1688 MonoMarshalType *info = mono_marshal_load_type_info (klass);
1690 for (int i = 0; i < info->num_fields; ++i) {
1691 if (info->fields [i].field == field) {
1692 if (!info->fields [i].mspec)
1693 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1695 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain, klass, info->fields [i].mspec, error);
1700 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1703 ICALL_EXPORT MonoReflectionFieldHandle
1704 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type, MonoError *error)
1710 mono_error_init (error);
1713 klass = handle->parent;
1715 klass = mono_class_from_mono_type (type);
1717 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1720 /* The managed code will throw the exception */
1721 return MONO_HANDLE_CAST (MonoReflectionField, NULL_HANDLE);
1724 return mono_field_get_object_handle (mono_domain_get (), klass, handle, error);
1727 ICALL_EXPORT MonoReflectionEventHandle
1728 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type, MonoError *error)
1734 mono_error_init (error);
1737 klass = handle->parent;
1739 klass = mono_class_from_mono_type (type);
1741 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1743 /* Managed code will throw an exception */
1744 return MONO_HANDLE_CAST (MonoReflectionEvent, NULL_HANDLE);
1747 return mono_event_get_object_handle (mono_domain_get (), klass, handle, error);
1751 ICALL_EXPORT MonoReflectionPropertyHandle
1752 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type, MonoError *error)
1754 mono_error_init (error);
1760 klass = handle->parent;
1762 klass = mono_class_from_mono_type (type);
1764 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1766 /* Managed code will throw an exception */
1767 return MONO_HANDLE_CAST (MonoReflectionProperty, NULL_HANDLE);
1770 return mono_property_get_object_handle (mono_domain_get (), klass, handle, error);
1773 ICALL_EXPORT MonoArrayHandle
1774 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
1776 mono_error_init (error);
1777 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1779 MonoType *type = mono_field_get_type_checked (field, error);
1781 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1783 return type_array_from_modifiers (field->parent->image, type, optional, error);
1787 vell_icall_get_method_attributes (MonoMethod *method)
1789 return method->flags;
1793 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1796 MonoReflectionType *rt;
1797 MonoDomain *domain = mono_domain_get ();
1798 MonoMethodSignature* sig;
1800 sig = mono_method_signature_checked (method, &error);
1801 if (!mono_error_ok (&error)) {
1802 mono_error_set_pending_exception (&error);
1806 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1807 if (!mono_error_ok (&error)) {
1808 mono_error_set_pending_exception (&error);
1812 MONO_STRUCT_SETREF (info, parent, rt);
1814 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1815 if (!mono_error_ok (&error)) {
1816 mono_error_set_pending_exception (&error);
1820 MONO_STRUCT_SETREF (info, ret, rt);
1822 info->attrs = method->flags;
1823 info->implattrs = method->iflags;
1824 if (sig->call_convention == MONO_CALL_DEFAULT)
1825 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1827 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1832 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1835 ICALL_EXPORT MonoArrayHandle
1836 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod *method, MonoReflectionMethodHandle member, MonoError *error)
1838 mono_error_init (error);
1839 MonoDomain *domain = mono_domain_get ();
1841 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1842 MONO_HANDLE_GET (reftype, member, reftype);
1843 MonoClass *klass = NULL;
1844 if (!MONO_HANDLE_IS_NULL (reftype))
1845 klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype, type));
1846 return mono_param_get_objects_internal (domain, method, klass, error);
1849 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1850 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method, MonoError *error)
1852 mono_error_init (error);
1853 MonoDomain *domain = mono_domain_get ();
1854 MonoReflectionMarshalAsAttributeHandle res = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
1856 MonoMarshalSpec **mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1857 mono_method_get_marshal_info (method, mspecs);
1860 MONO_HANDLE_ASSIGN (res, mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], error));
1866 for (int i = mono_method_signature (method)->param_count; i >= 0; i--)
1868 mono_metadata_free_marshal_spec (mspecs [i]);
1875 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1877 MonoClass *parent = field->field->parent;
1878 mono_class_setup_fields (parent);
1880 return field->field->offset - sizeof (MonoObject);
1883 ICALL_EXPORT MonoReflectionTypeHandle
1884 ves_icall_MonoField_GetParentType (MonoReflectionFieldHandle field, MonoBoolean declaring, MonoError *error)
1886 mono_error_init (error);
1887 MonoDomain *domain = MONO_HANDLE_DOMAIN (field);
1891 MonoClassField *f = MONO_HANDLE_GETVAL (field, field);
1894 parent = MONO_HANDLE_GETVAL (field, klass);
1897 return mono_type_get_object_handle (domain, &parent->byval_arg, error);
1900 ICALL_EXPORT MonoObject *
1901 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1904 MonoClass *fklass = field->klass;
1905 MonoClassField *cf = field->field;
1906 MonoDomain *domain = mono_object_domain (field);
1908 if (fklass->image->assembly->ref_only) {
1909 mono_set_pending_exception (mono_get_exception_invalid_operation (
1910 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1914 if (mono_security_core_clr_enabled () &&
1915 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1916 mono_error_set_pending_exception (&error);
1920 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1921 mono_error_set_pending_exception (&error);
1926 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1929 MonoClassField *cf = field->field;
1933 if (field->klass->image->assembly->ref_only) {
1934 mono_set_pending_exception (mono_get_exception_invalid_operation (
1935 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1939 if (mono_security_core_clr_enabled () &&
1940 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1941 mono_error_set_pending_exception (&error);
1945 type = mono_field_get_type_checked (cf, &error);
1946 if (!mono_error_ok (&error)) {
1947 mono_error_set_pending_exception (&error);
1951 v = (gchar *) value;
1953 switch (type->type) {
1956 case MONO_TYPE_BOOLEAN:
1959 case MONO_TYPE_CHAR:
1968 case MONO_TYPE_VALUETYPE:
1971 v += sizeof (MonoObject);
1973 case MONO_TYPE_STRING:
1974 case MONO_TYPE_OBJECT:
1975 case MONO_TYPE_CLASS:
1976 case MONO_TYPE_ARRAY:
1977 case MONO_TYPE_SZARRAY:
1980 case MONO_TYPE_GENERICINST: {
1981 MonoGenericClass *gclass = type->data.generic_class;
1982 g_assert (!gclass->context.class_inst->is_open);
1984 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1985 MonoClass *nklass = mono_class_from_mono_type (type);
1986 MonoObject *nullable;
1989 * Convert the boxed vtype into a Nullable structure.
1990 * This is complicated by the fact that Nullables have
1991 * a variable structure.
1993 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
1994 if (!mono_error_ok (&error)) {
1995 mono_error_set_pending_exception (&error);
1999 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2001 v = (gchar *)mono_object_unbox (nullable);
2004 if (gclass->container_class->valuetype && (v != NULL))
2005 v += sizeof (MonoObject);
2009 g_error ("type 0x%x not handled in "
2010 "ves_icall_FieldInfo_SetValueInternal", type->type);
2015 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2016 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2017 if (!is_ok (&error)) {
2018 mono_error_set_pending_exception (&error);
2021 if (!vtable->initialized) {
2022 if (!mono_runtime_class_init_full (vtable, &error)) {
2023 mono_error_set_pending_exception (&error);
2027 mono_field_static_set_value (vtable, cf, v);
2029 mono_field_set_value (obj, cf, v);
2034 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2043 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2044 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2048 if (MONO_TYPE_IS_REFERENCE (f->type))
2049 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2051 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2054 ICALL_EXPORT MonoObject *
2055 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2057 MonoObject *o = NULL;
2058 MonoClassField *field = rfield->field;
2060 MonoDomain *domain = mono_object_domain (rfield);
2062 MonoTypeEnum def_type;
2063 const char *def_value;
2067 mono_class_init (field->parent);
2069 t = mono_field_get_type_checked (field, &error);
2070 if (!mono_error_ok (&error)) {
2071 mono_error_set_pending_exception (&error);
2075 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2076 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2080 if (image_is_dynamic (field->parent->image)) {
2081 MonoClass *klass = field->parent;
2082 int fidx = field - klass->fields;
2083 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2085 g_assert (def_values);
2086 def_type = def_values [fidx].def_type;
2087 def_value = def_values [fidx].data;
2089 if (def_type == MONO_TYPE_END) {
2090 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2094 def_value = mono_class_get_field_default_value (field, &def_type);
2095 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2097 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2102 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2106 case MONO_TYPE_BOOLEAN:
2109 case MONO_TYPE_CHAR:
2117 case MONO_TYPE_R8: {
2120 /* boxed value type */
2121 t = g_new0 (MonoType, 1);
2123 klass = mono_class_from_mono_type (t);
2125 o = mono_object_new_checked (domain, klass, &error);
2126 if (!mono_error_ok (&error)) {
2127 mono_error_set_pending_exception (&error);
2130 v = ((gchar *) o) + sizeof (MonoObject);
2131 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2132 if (mono_error_set_pending_exception (&error))
2136 case MONO_TYPE_STRING:
2137 case MONO_TYPE_CLASS:
2138 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2139 if (mono_error_set_pending_exception (&error))
2143 g_assert_not_reached ();
2149 ICALL_EXPORT MonoReflectionTypeHandle
2150 ves_icall_MonoField_ResolveType (MonoReflectionFieldHandle ref_field, MonoError *error)
2152 mono_error_init (error);
2153 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_field);
2154 MonoClassField *field = MONO_HANDLE_GETVAL (ref_field, field);
2155 MonoType *type = mono_field_get_type_checked (field, error);
2156 if (!is_ok (error)) {
2157 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2159 return mono_type_get_object_handle (domain, type, error);
2162 /* From MonoProperty.cs */
2164 PInfo_Attributes = 1,
2165 PInfo_GetMethod = 1 << 1,
2166 PInfo_SetMethod = 1 << 2,
2167 PInfo_ReflectedType = 1 << 3,
2168 PInfo_DeclaringType = 1 << 4,
2173 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2176 MonoReflectionType *rt;
2177 MonoReflectionMethod *rm;
2178 MonoDomain *domain = mono_object_domain (property);
2179 const MonoProperty *pproperty = property->property;
2181 if ((req_info & PInfo_ReflectedType) != 0) {
2182 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2183 if (mono_error_set_pending_exception (&error))
2186 MONO_STRUCT_SETREF (info, parent, rt);
2188 if ((req_info & PInfo_DeclaringType) != 0) {
2189 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2190 if (mono_error_set_pending_exception (&error))
2193 MONO_STRUCT_SETREF (info, declaring_type, rt);
2196 if ((req_info & PInfo_Name) != 0)
2197 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2199 if ((req_info & PInfo_Attributes) != 0)
2200 info->attrs = pproperty->attrs;
2202 if ((req_info & PInfo_GetMethod) != 0) {
2203 if (pproperty->get &&
2204 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2205 pproperty->get->klass == property->klass)) {
2206 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2207 if (mono_error_set_pending_exception (&error))
2213 MONO_STRUCT_SETREF (info, get, rm);
2215 if ((req_info & PInfo_SetMethod) != 0) {
2216 if (pproperty->set &&
2217 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2218 pproperty->set->klass == property->klass)) {
2219 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2220 if (mono_error_set_pending_exception (&error))
2226 MONO_STRUCT_SETREF (info, set, rm);
2229 * There may be other methods defined for properties, though, it seems they are not exposed
2230 * in the reflection API
2235 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2238 MonoReflectionType *rt;
2239 MonoReflectionMethod *rm;
2240 MonoDomain *domain = mono_object_domain (event);
2242 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2243 if (mono_error_set_pending_exception (&error))
2246 MONO_STRUCT_SETREF (info, reflected_type, rt);
2248 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2249 if (mono_error_set_pending_exception (&error))
2252 MONO_STRUCT_SETREF (info, declaring_type, rt);
2254 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2255 info->attrs = event->event->attrs;
2257 if (event->event->add) {
2258 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2259 if (mono_error_set_pending_exception (&error))
2265 MONO_STRUCT_SETREF (info, add_method, rm);
2267 if (event->event->remove) {
2268 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2269 if (mono_error_set_pending_exception (&error))
2275 MONO_STRUCT_SETREF (info, remove_method, rm);
2277 if (event->event->raise) {
2278 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2279 if (mono_error_set_pending_exception (&error))
2285 MONO_STRUCT_SETREF (info, raise_method, rm);
2287 #ifndef MONO_SMALL_CONFIG
2288 if (event->event->other) {
2290 while (event->event->other [n])
2292 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2293 if (mono_error_set_pending_exception (&error))
2295 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2297 for (i = 0; i < n; i++) {
2298 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2299 if (mono_error_set_pending_exception (&error))
2301 mono_array_setref (info->other_methods, i, rm);
2308 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2313 mono_class_setup_interfaces (klass, error);
2314 if (!mono_error_ok (error))
2317 for (i = 0; i < klass->interface_count; i++) {
2318 ic = klass->interfaces [i];
2319 g_hash_table_insert (ifaces, ic, ic);
2321 collect_interfaces (ic, ifaces, error);
2322 if (!mono_error_ok (error))
2328 MonoArray *iface_array;
2329 MonoGenericContext *context;
2333 } FillIfaceArrayData;
2336 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2338 MonoReflectionType *rt;
2339 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2340 MonoClass *ic = (MonoClass *)key;
2341 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2343 if (!mono_error_ok (data->error))
2346 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2347 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2348 if (!mono_error_ok (data->error))
2352 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2353 if (!mono_error_ok (data->error))
2356 mono_array_setref (data->iface_array, data->next_idx++, rt);
2359 mono_metadata_free_type (inflated);
2363 get_interfaces_hash (gconstpointer v1)
2365 MonoClass *k = (MonoClass*)v1;
2367 return k->type_token;
2370 ICALL_EXPORT MonoArray*
2371 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2374 MonoClass *klass = mono_class_from_mono_type (type->type);
2376 FillIfaceArrayData data = { 0 };
2379 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2381 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2382 data.context = mono_class_get_context (klass);
2383 klass = mono_class_get_generic_class (klass)->container_class;
2386 for (parent = klass; parent; parent = parent->parent) {
2387 mono_class_setup_interfaces (parent, &error);
2388 if (!mono_error_ok (&error))
2390 collect_interfaces (parent, iface_hash, &error);
2391 if (!mono_error_ok (&error))
2395 data.error = &error;
2396 data.domain = mono_object_domain (type);
2398 len = g_hash_table_size (iface_hash);
2400 g_hash_table_destroy (iface_hash);
2401 if (!data.domain->empty_types) {
2402 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2403 if (!is_ok (&error))
2406 return data.domain->empty_types;
2409 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2410 if (!is_ok (&error))
2412 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2413 if (!mono_error_ok (&error))
2416 g_hash_table_destroy (iface_hash);
2417 return data.iface_array;
2420 g_hash_table_destroy (iface_hash);
2421 mono_error_set_pending_exception (&error);
2426 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2428 gboolean variance_used;
2429 MonoClass *klass = mono_class_from_mono_type (type->type);
2430 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2431 MonoReflectionMethod *member;
2434 int i = 0, len, ioffset;
2438 mono_class_init_checked (klass, &error);
2439 if (mono_error_set_pending_exception (&error))
2441 mono_class_init_checked (iclass, &error);
2442 if (mono_error_set_pending_exception (&error))
2445 mono_class_setup_vtable (klass);
2447 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2451 len = mono_class_num_methods (iclass);
2452 domain = mono_object_domain (type);
2453 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2454 if (mono_error_set_pending_exception (&error))
2456 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2457 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2458 if (mono_error_set_pending_exception (&error))
2460 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2462 while ((method = mono_class_get_methods (iclass, &iter))) {
2463 member = mono_method_get_object_checked (domain, method, iclass, &error);
2464 if (mono_error_set_pending_exception (&error))
2466 mono_array_setref (*methods, i, member);
2467 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2468 if (mono_error_set_pending_exception (&error))
2470 mono_array_setref (*targets, i, member);
2477 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2480 MonoClass *klass = mono_class_from_mono_type (type->type);
2482 mono_class_init_checked (klass, &error);
2483 if (mono_error_set_pending_exception (&error))
2486 if (image_is_dynamic (klass->image)) {
2487 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2488 *packing = tb->packing_size;
2489 *size = tb->class_size;
2491 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2495 ICALL_EXPORT MonoReflectionTypeHandle
2496 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionTypeHandle ref_type, MonoError *error)
2498 mono_error_init (error);
2500 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2501 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2503 if (!type->byref && type->type == MONO_TYPE_SZARRAY) {
2504 return mono_type_get_object_handle (domain, &type->data.klass->byval_arg, error);
2507 MonoClass *klass = mono_class_from_mono_type (type);
2508 mono_class_init_checked (klass, error);
2510 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2512 // GetElementType should only return a type for:
2513 // Array Pointer PassedByRef
2515 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2516 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2517 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2518 else if (klass->element_class && type->type == MONO_TYPE_PTR)
2519 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2521 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2524 ICALL_EXPORT MonoReflectionTypeHandle
2525 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionTypeHandle ref_type, MonoError *error)
2527 mono_error_init (error);
2529 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2530 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2533 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2535 MonoClass *klass = mono_class_from_mono_type (type);
2537 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2539 return mono_type_get_object_handle (domain, &klass->parent->byval_arg, error);
2542 ICALL_EXPORT MonoBoolean
2543 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionTypeHandle ref_type, MonoError *error)
2545 mono_error_init (error);
2546 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2547 return type->type == MONO_TYPE_PTR;
2550 ICALL_EXPORT MonoBoolean
2551 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type, MonoError *error)
2553 mono_error_init (error);
2554 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2555 return (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)));
2558 ICALL_EXPORT MonoBoolean
2559 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type, MonoError *error)
2561 mono_error_init (error);
2562 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2566 ICALL_EXPORT MonoBoolean
2567 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionTypeHandle ref_type, MonoError *error)
2569 mono_error_init (error);
2570 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2571 MonoClass *klass = mono_class_from_mono_type (type);
2572 mono_class_init_checked (klass, error);
2576 return mono_class_is_com_object (klass);
2579 ICALL_EXPORT guint32
2580 ves_icall_reflection_get_token (MonoObjectHandle obj, MonoError *error)
2582 mono_error_init (error);
2583 return mono_reflection_get_token_checked (obj, error);
2586 ICALL_EXPORT MonoReflectionModuleHandle
2587 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2589 mono_error_init (error);
2590 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2591 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2592 MonoClass *klass = mono_class_from_mono_type (t);
2593 return mono_module_get_object_handle (domain, klass->image, error);
2596 ICALL_EXPORT MonoReflectionAssemblyHandle
2597 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2599 mono_error_init (error);
2600 MonoDomain *domain = mono_domain_get ();
2601 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2602 MonoClass *klass = mono_class_from_mono_type (t);
2603 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2606 ICALL_EXPORT MonoReflectionType*
2607 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2610 MonoReflectionType *ret;
2611 MonoDomain *domain = mono_domain_get ();
2614 if (type->type->byref)
2616 if (type->type->type == MONO_TYPE_VAR) {
2617 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2618 klass = param ? param->owner.klass : NULL;
2619 } else if (type->type->type == MONO_TYPE_MVAR) {
2620 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2621 klass = param ? param->owner.method->klass : NULL;
2623 klass = mono_class_from_mono_type (type->type)->nested_in;
2629 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2630 mono_error_set_pending_exception (&error);
2635 ICALL_EXPORT MonoStringHandle
2636 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2638 MonoDomain *domain = mono_domain_get ();
2639 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2640 MonoClass *klass = mono_class_from_mono_type (type);
2643 char *n = g_strdup_printf ("%s&", klass->name);
2644 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2650 return mono_string_new_handle (domain, klass->name, error);
2654 ICALL_EXPORT MonoStringHandle
2655 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2657 MonoDomain *domain = mono_domain_get ();
2658 MonoClass *klass = mono_class_from_mono_type_handle (type);
2660 while (klass->nested_in)
2661 klass = klass->nested_in;
2663 if (klass->name_space [0] == '\0')
2664 return NULL_HANDLE_STRING;
2666 return mono_string_new_handle (domain, klass->name_space, error);
2670 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionTypeHandle ref_type, MonoError *error)
2672 mono_error_init (error);
2673 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2675 if (type->type != MONO_TYPE_ARRAY && type->type != MONO_TYPE_SZARRAY) {
2676 mono_error_set_argument (error, "type", "Type must be an array type");
2680 MonoClass *klass = mono_class_from_mono_type (type);
2686 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2688 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2691 ICALL_EXPORT MonoArray*
2692 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2695 MonoReflectionType *rt;
2697 MonoClass *klass, *pklass;
2698 MonoDomain *domain = mono_object_domain (type);
2701 klass = mono_class_from_mono_type (type->type);
2703 if (mono_class_is_gtd (klass)) {
2704 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2705 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2706 if (mono_error_set_pending_exception (&error))
2708 for (i = 0; i < container->type_argc; ++i) {
2709 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2711 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2712 if (mono_error_set_pending_exception (&error))
2715 mono_array_setref (res, i, rt);
2717 } else if (mono_class_is_ginst (klass)) {
2718 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2719 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2720 if (mono_error_set_pending_exception (&error))
2722 for (i = 0; i < inst->type_argc; ++i) {
2723 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2724 if (mono_error_set_pending_exception (&error))
2727 mono_array_setref (res, i, rt);
2735 ICALL_EXPORT gboolean
2736 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionTypeHandle ref_type, MonoError *error)
2738 mono_error_init (error);
2740 if (!IS_MONOTYPE (MONO_HANDLE_RAW(ref_type)))
2743 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2747 MonoClass *klass = mono_class_from_mono_type (type);
2748 return mono_class_is_gtd (klass);
2751 ICALL_EXPORT MonoReflectionTypeHandle
2752 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionTypeHandle ref_type, MonoError *error)
2754 mono_error_init (error);
2755 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2757 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW (MonoReflectionType, NULL);
2762 MonoClass *klass = mono_class_from_mono_type (type);
2764 if (mono_class_is_gtd (klass)) {
2765 /* check this one */
2766 MONO_HANDLE_ASSIGN (ret, ref_type);
2769 if (mono_class_is_ginst (klass)) {
2770 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2772 guint32 ref_info_handle = mono_class_get_ref_info_handle (klass);
2774 if (generic_class->wastypebuilder && ref_info_handle) {
2775 MonoObjectHandle tb = mono_gchandle_get_target_handle (ref_info_handle);
2776 g_assert (!MONO_HANDLE_IS_NULL (tb));
2777 MONO_HANDLE_ASSIGN (ret, tb);
2779 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2780 MONO_HANDLE_ASSIGN (ret, mono_type_get_object_handle (domain, &generic_class->byval_arg, error));
2787 ICALL_EXPORT MonoReflectionType*
2788 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2791 MonoReflectionType *ret;
2793 MonoType *geninst, **types;
2796 g_assert (IS_MONOTYPE (type));
2797 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2798 if (mono_error_set_pending_exception (&error))
2801 count = mono_array_length (type_array);
2802 types = g_new0 (MonoType *, count);
2804 for (i = 0; i < count; i++) {
2805 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2806 types [i] = t->type;
2809 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2812 mono_error_set_pending_exception (&error);
2816 klass = mono_class_from_mono_type (geninst);
2818 /*we might inflate to the GTD*/
2819 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2820 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2824 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2825 mono_error_set_pending_exception (&error);
2830 ICALL_EXPORT gboolean
2831 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionTypeHandle ref_type, MonoError *error)
2833 mono_error_init (error);
2836 if (!IS_MONOTYPE (MONO_HANDLE_RAW (ref_type)))
2839 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2843 klass = mono_class_from_mono_type (type);
2844 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2848 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2850 if (!IS_MONOTYPE (type))
2853 if (is_generic_parameter (type->type))
2854 return mono_type_get_generic_param_num (type->type);
2858 ICALL_EXPORT MonoGenericParamInfo *
2859 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionTypeHandle ref_type, MonoError *error)
2861 mono_error_init (error);
2862 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2863 return mono_generic_param_info (type->data.generic_param);
2866 ICALL_EXPORT MonoBoolean
2867 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionTypeHandle ref_type, MonoError *error)
2869 MonoType *type = MONO_HANDLE_GETVAL(ref_type, type);
2870 return is_generic_parameter (type);
2873 ICALL_EXPORT MonoReflectionMethod*
2874 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2875 MonoReflectionMethod* generic)
2882 MonoReflectionMethod *ret = NULL;
2884 domain = ((MonoObject *)type)->vtable->domain;
2886 klass = mono_class_from_mono_type (type->type);
2887 mono_class_init_checked (klass, &error);
2888 if (mono_error_set_pending_exception (&error))
2892 while ((method = mono_class_get_methods (klass, &iter))) {
2893 if (method->token == generic->method->token) {
2894 ret = mono_method_get_object_checked (domain, method, klass, &error);
2895 if (mono_error_set_pending_exception (&error))
2903 ICALL_EXPORT MonoReflectionMethod *
2904 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2907 MonoType *type = ref_type->type;
2909 MonoReflectionMethod *ret = NULL;
2911 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2912 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2915 if (type->type == MONO_TYPE_VAR)
2918 method = mono_type_get_generic_param_owner (type)->owner.method;
2921 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2922 if (!mono_error_ok (&error))
2923 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2927 ICALL_EXPORT MonoBoolean
2928 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2930 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2934 ICALL_EXPORT MonoBoolean
2935 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2937 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2942 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2944 MonoDomain *domain = mono_domain_get ();
2945 MonoImage *image = method->method->klass->image;
2946 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2947 MonoTableInfo *tables = image->tables;
2948 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2949 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2950 guint32 im_cols [MONO_IMPLMAP_SIZE];
2951 guint32 scope_token;
2952 const char *import = NULL;
2953 const char *scope = NULL;
2955 if (image_is_dynamic (image)) {
2956 MonoReflectionMethodAux *method_aux =
2957 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2959 import = method_aux->dllentry;
2960 scope = method_aux->dll;
2963 if (!import || !scope) {
2964 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2969 if (piinfo->implmap_idx) {
2970 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2972 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2973 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2974 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2975 scope = mono_metadata_string_heap (image, scope_token);
2979 *flags = piinfo->piflags;
2980 *entry_point = mono_string_new (domain, import);
2981 *dll_name = mono_string_new (domain, scope);
2984 ICALL_EXPORT MonoReflectionMethod *
2985 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2987 MonoMethodInflated *imethod;
2989 MonoReflectionMethod *ret = NULL;
2992 if (method->method->is_generic)
2995 if (!method->method->is_inflated)
2998 imethod = (MonoMethodInflated *) method->method;
3000 result = imethod->declaring;
3001 /* Not a generic method. */
3002 if (!result->is_generic)
3005 if (image_is_dynamic (method->method->klass->image)) {
3006 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3007 MonoReflectionMethod *res;
3010 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3011 * the dynamic case as well ?
3013 mono_image_lock ((MonoImage*)image);
3014 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3015 mono_image_unlock ((MonoImage*)image);
3021 if (imethod->context.class_inst) {
3022 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3023 /*Generic methods gets the context of the GTD.*/
3024 if (mono_class_get_context (klass)) {
3025 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3026 if (!mono_error_ok (&error))
3031 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3033 if (!mono_error_ok (&error))
3034 mono_error_set_pending_exception (&error);
3038 ICALL_EXPORT gboolean
3039 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3041 return mono_method_signature (method->method)->generic_param_count != 0;
3044 ICALL_EXPORT gboolean
3045 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3047 return method->method->is_generic;
3050 ICALL_EXPORT MonoArray*
3051 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3054 MonoReflectionType *rt;
3059 domain = mono_object_domain (method);
3061 if (method->method->is_inflated) {
3062 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3065 count = inst->type_argc;
3066 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3067 if (mono_error_set_pending_exception (&error))
3070 for (i = 0; i < count; i++) {
3071 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3072 if (mono_error_set_pending_exception (&error))
3075 mono_array_setref (res, i, rt);
3082 count = mono_method_signature (method->method)->generic_param_count;
3083 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3084 if (mono_error_set_pending_exception (&error))
3087 for (i = 0; i < count; i++) {
3088 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3089 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3090 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3092 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3093 if (mono_error_set_pending_exception (&error))
3096 mono_array_setref (res, i, rt);
3102 ICALL_EXPORT MonoObject *
3103 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3107 * Invoke from reflection is supposed to always be a virtual call (the API
3108 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3109 * greater flexibility.
3111 MonoMethod *m = method->method;
3112 MonoMethodSignature *sig = mono_method_signature (m);
3115 void *obj = this_arg;
3119 if (mono_security_core_clr_enabled () &&
3120 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3121 mono_error_set_pending_exception (&error);
3125 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3126 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3127 mono_error_cleanup (&error); /* FIXME does this make sense? */
3128 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3133 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3134 if (!is_ok (&error)) {
3135 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3138 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3139 char *target_name = mono_type_get_full_name (m->klass);
3140 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3141 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3143 g_free (target_name);
3147 m = mono_object_get_virtual_method (this_arg, m);
3148 /* must pass the pointer to the value for valuetype methods */
3149 if (m->klass->valuetype)
3150 obj = mono_object_unbox (this_arg);
3151 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3152 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3157 if (sig->ret->byref) {
3158 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"));
3162 pcount = params? mono_array_length (params): 0;
3163 if (pcount != sig->param_count) {
3164 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3168 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3169 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."));
3173 image = m->klass->image;
3174 if (image->assembly->ref_only) {
3175 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."));
3179 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3180 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3184 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3188 intptr_t *lower_bounds;
3189 pcount = mono_array_length (params);
3190 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3191 /* Note: the synthetized array .ctors have int32 as argument type */
3192 for (i = 0; i < pcount; ++i)
3193 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3195 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3196 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3197 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3198 if (!mono_error_ok (&error)) {
3199 mono_error_set_pending_exception (&error);
3203 for (i = 0; i < mono_array_length (arr); ++i) {
3204 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3205 if (!mono_error_ok (&error)) {
3206 mono_error_set_pending_exception (&error);
3209 mono_array_setref_fast (arr, i, subarray);
3211 return (MonoObject*)arr;
3214 if (m->klass->rank == pcount) {
3215 /* Only lengths provided. */
3216 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3217 if (!mono_error_ok (&error)) {
3218 mono_error_set_pending_exception (&error);
3222 return (MonoObject*)arr;
3224 g_assert (pcount == (m->klass->rank * 2));
3225 /* The arguments are lower-bound-length pairs */
3226 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3228 for (i = 0; i < pcount / 2; ++i) {
3229 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3230 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3233 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3234 if (!mono_error_ok (&error)) {
3235 mono_error_set_pending_exception (&error);
3239 return (MonoObject*)arr;
3242 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3243 mono_error_set_pending_exception (&error);
3247 #ifndef DISABLE_REMOTING
3248 ICALL_EXPORT MonoObject *
3249 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3252 MonoDomain *domain = mono_object_domain (method);
3253 MonoMethod *m = method->method;
3254 MonoMethodSignature *sig = mono_method_signature (m);
3255 MonoArray *out_args;
3257 int i, j, outarg_count = 0;
3259 if (m->klass == mono_defaults.object_class) {
3260 if (!strcmp (m->name, "FieldGetter")) {
3261 MonoClass *k = this_arg->vtable->klass;
3265 /* If this is a proxy, then it must be a CBO */
3266 if (k == mono_defaults.transparent_proxy_class) {
3267 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3268 this_arg = tp->rp->unwrapped_server;
3269 g_assert (this_arg);
3270 k = this_arg->vtable->klass;
3273 name = mono_array_get (params, MonoString *, 1);
3274 str = mono_string_to_utf8_checked (name, &error);
3275 if (mono_error_set_pending_exception (&error))
3279 MonoClassField* field = mono_class_get_field_from_name (k, str);
3282 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3283 if (field_klass->valuetype) {
3284 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3285 if (mono_error_set_pending_exception (&error))
3288 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3290 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3291 if (mono_error_set_pending_exception (&error))
3293 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3294 mono_array_setref (out_args, 0, result);
3301 g_assert_not_reached ();
3303 } else if (!strcmp (m->name, "FieldSetter")) {
3304 MonoClass *k = this_arg->vtable->klass;
3310 /* If this is a proxy, then it must be a CBO */
3311 if (k == mono_defaults.transparent_proxy_class) {
3312 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3313 this_arg = tp->rp->unwrapped_server;
3314 g_assert (this_arg);
3315 k = this_arg->vtable->klass;
3318 name = mono_array_get (params, MonoString *, 1);
3319 str = mono_string_to_utf8_checked (name, &error);
3320 if (mono_error_set_pending_exception (&error))
3324 MonoClassField* field = mono_class_get_field_from_name (k, str);
3327 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3328 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3330 if (field_klass->valuetype) {
3331 size = mono_type_size (field->type, &align);
3332 g_assert (size == mono_class_value_size (field_klass, NULL));
3333 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3335 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3338 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3339 if (mono_error_set_pending_exception (&error))
3341 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3350 g_assert_not_reached ();
3355 for (i = 0; i < mono_array_length (params); i++) {
3356 if (sig->params [i]->byref)
3360 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3361 if (mono_error_set_pending_exception (&error))
3364 /* handle constructors only for objects already allocated */
3365 if (!strcmp (method->method->name, ".ctor"))
3366 g_assert (this_arg);
3368 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3369 g_assert (!method->method->klass->valuetype);
3370 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3371 if (mono_error_set_pending_exception (&error))
3374 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3375 if (sig->params [i]->byref) {
3377 arg = mono_array_get (params, gpointer, i);
3378 mono_array_setref (out_args, j, arg);
3383 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3390 read_enum_value (const char *mem, int type)
3393 case MONO_TYPE_BOOLEAN:
3395 return *(guint8*)mem;
3397 return *(gint8*)mem;
3398 case MONO_TYPE_CHAR:
3400 return read16 (mem);
3402 return (gint16) read16 (mem);
3404 return read32 (mem);
3406 return (gint32) read32 (mem);
3409 return read64 (mem);
3411 g_assert_not_reached ();
3417 write_enum_value (char *mem, int type, guint64 value)
3421 case MONO_TYPE_I1: {
3422 guint8 *p = (guint8*)mem;
3428 case MONO_TYPE_CHAR: {
3429 guint16 *p = (guint16 *)mem;
3434 case MONO_TYPE_I4: {
3435 guint32 *p = (guint32 *)mem;
3440 case MONO_TYPE_I8: {
3441 guint64 *p = (guint64 *)mem;
3446 g_assert_not_reached ();
3451 ICALL_EXPORT MonoObject *
3452 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3460 domain = mono_object_domain (enumType);
3461 enumc = mono_class_from_mono_type (enumType->type);
3463 mono_class_init_checked (enumc, &error);
3464 if (mono_error_set_pending_exception (&error))
3467 etype = mono_class_enum_basetype (enumc);
3469 res = mono_object_new_checked (domain, enumc, &error);
3470 if (mono_error_set_pending_exception (&error))
3472 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3477 ICALL_EXPORT MonoBoolean
3478 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3480 int size = mono_class_value_size (a->vtable->klass, NULL);
3481 guint64 a_val = 0, b_val = 0;
3483 memcpy (&a_val, mono_object_unbox (a), size);
3484 memcpy (&b_val, mono_object_unbox (b), size);
3486 return (a_val & b_val) == b_val;
3489 ICALL_EXPORT MonoObject *
3490 ves_icall_System_Enum_get_value (MonoObject *eobj)
3502 g_assert (eobj->vtable->klass->enumtype);
3504 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3505 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3506 if (mono_error_set_pending_exception (&error))
3508 dst = (char *)res + sizeof (MonoObject);
3509 src = (char *)eobj + sizeof (MonoObject);
3510 size = mono_class_value_size (enumc, NULL);
3512 memcpy (dst, src, size);
3517 ICALL_EXPORT MonoReflectionType *
3518 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3521 MonoReflectionType *ret;
3525 klass = mono_class_from_mono_type (type->type);
3526 mono_class_init_checked (klass, &error);
3527 if (mono_error_set_pending_exception (&error))
3530 etype = mono_class_enum_basetype (klass);
3532 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3536 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3537 mono_error_set_pending_exception (&error);
3543 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3545 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3546 gpointer odata = (char *)other + sizeof (MonoObject);
3547 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3548 g_assert (basetype);
3553 if (eobj->vtable->klass != other->vtable->klass)
3556 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3557 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3558 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3561 return me > other ? 1 : -1; \
3564 switch (basetype->type) {
3566 COMPARE_ENUM_VALUES (guint8);
3568 COMPARE_ENUM_VALUES (gint8);
3569 case MONO_TYPE_CHAR:
3571 COMPARE_ENUM_VALUES (guint16);
3573 COMPARE_ENUM_VALUES (gint16);
3575 COMPARE_ENUM_VALUES (guint32);
3577 COMPARE_ENUM_VALUES (gint32);
3579 COMPARE_ENUM_VALUES (guint64);
3581 COMPARE_ENUM_VALUES (gint64);
3585 #undef COMPARE_ENUM_VALUES
3586 /* indicates that the enum was of an unsupported unerlying type */
3591 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3593 gpointer data = (char *)eobj + sizeof (MonoObject);
3594 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3595 g_assert (basetype);
3597 switch (basetype->type) {
3598 case MONO_TYPE_I1: {
3599 gint8 value = *((gint8*)data);
3600 return ((int)value ^ (int)value << 8);
3603 return *((guint8*)data);
3604 case MONO_TYPE_CHAR:
3606 return *((guint16*)data);
3608 case MONO_TYPE_I2: {
3609 gint16 value = *((gint16*)data);
3610 return ((int)(guint16)value | (((int)value) << 16));
3613 return *((guint32*)data);
3615 return *((gint32*)data);
3617 case MONO_TYPE_I8: {
3618 gint64 value = *((gint64*)data);
3619 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3622 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3628 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3630 mono_error_init (error);
3631 HANDLE_FUNCTION_ENTER();
3632 guint64 field_value;
3634 MonoTypeEnum def_type;
3636 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3638 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3640 if (mono_field_is_deleted (field))
3642 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3645 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3647 p = mono_class_get_field_default_value (field, &def_type);
3648 /* len = */ mono_metadata_decode_blob_size (p, &p);
3650 field_value = read_enum_value (p, base_type);
3651 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3653 if (*previous_value > field_value)
3656 *previous_value = field_value;
3659 HANDLE_FUNCTION_RETURN();
3662 ICALL_EXPORT MonoBoolean
3663 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3665 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3666 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3667 guint j = 0, nvalues;
3669 MonoClassField *field;
3671 guint64 previous_value = 0;
3672 gboolean sorted = TRUE;
3674 mono_error_init (error);
3675 mono_class_init_checked (enumc, error);
3676 return_val_if_nok (error, FALSE);
3678 if (!enumc->enumtype) {
3679 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3683 base_type = mono_class_enum_basetype (enumc)->type;
3685 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3686 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3687 return_val_if_nok (error, FALSE);
3688 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3689 return_val_if_nok (error, FALSE);
3692 while ((field = mono_class_get_fields (enumc, &iter))) {
3693 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3697 return_val_if_nok (error, FALSE);
3703 BFLAGS_IgnoreCase = 1,
3704 BFLAGS_DeclaredOnly = 2,
3705 BFLAGS_Instance = 4,
3707 BFLAGS_Public = 0x10,
3708 BFLAGS_NonPublic = 0x20,
3709 BFLAGS_FlattenHierarchy = 0x40,
3710 BFLAGS_InvokeMethod = 0x100,
3711 BFLAGS_CreateInstance = 0x200,
3712 BFLAGS_GetField = 0x400,
3713 BFLAGS_SetField = 0x800,
3714 BFLAGS_GetProperty = 0x1000,
3715 BFLAGS_SetProperty = 0x2000,
3716 BFLAGS_ExactBinding = 0x10000,
3717 BFLAGS_SuppressChangeType = 0x20000,
3718 BFLAGS_OptionalParamBinding = 0x40000
3721 ICALL_EXPORT GPtrArray*
3722 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3725 MonoClass *startklass, *klass;
3728 int (*compare_func) (const char *s1, const char *s2) = NULL;
3729 MonoClassField *field;
3731 if (type->type->byref) {
3732 return g_ptr_array_new ();
3735 mono_error_init (&error);
3737 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3739 klass = startklass = mono_class_from_mono_type (type->type);
3741 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3744 if (mono_class_has_failure (klass)) {
3745 mono_error_set_for_class_failure (&error, klass);
3750 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3751 guint32 flags = mono_field_get_flags (field);
3753 if (mono_field_is_deleted_with_flags (field, flags))
3755 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3756 if (bflags & BFLAGS_Public)
3758 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3759 if (bflags & BFLAGS_NonPublic) {
3766 if (flags & FIELD_ATTRIBUTE_STATIC) {
3767 if (bflags & BFLAGS_Static)
3768 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3771 if (bflags & BFLAGS_Instance)
3778 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3781 g_ptr_array_add (ptr_array, field);
3783 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3789 g_ptr_array_free (ptr_array, TRUE);
3790 mono_error_set_pending_exception (&error);
3795 method_nonpublic (MonoMethod* method, gboolean start_klass)
3797 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3798 case METHOD_ATTRIBUTE_ASSEM:
3799 return (start_klass || mono_defaults.generic_ilist_class);
3800 case METHOD_ATTRIBUTE_PRIVATE:
3802 case METHOD_ATTRIBUTE_PUBLIC:
3810 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3813 MonoClass *startklass;
3817 /*FIXME, use MonoBitSet*/
3818 guint32 method_slots_default [8];
3819 guint32 *method_slots = NULL;
3820 int (*compare_func) (const char *s1, const char *s2) = NULL;
3822 array = g_ptr_array_new ();
3824 mono_error_init (error);
3827 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3829 /* An optimization for calls made from Delegate:CreateDelegate () */
3830 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3831 method = mono_get_delegate_invoke (klass);
3834 g_ptr_array_add (array, method);
3838 mono_class_setup_methods (klass);
3839 mono_class_setup_vtable (klass);
3840 if (mono_class_has_failure (klass))
3843 if (is_generic_parameter (&klass->byval_arg))
3844 nslots = mono_class_get_vtable_size (klass->parent);
3846 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3847 if (nslots >= sizeof (method_slots_default) * 8) {
3848 method_slots = g_new0 (guint32, nslots / 32 + 1);
3850 method_slots = method_slots_default;
3851 memset (method_slots, 0, sizeof (method_slots_default));
3854 mono_class_setup_methods (klass);
3855 mono_class_setup_vtable (klass);
3856 if (mono_class_has_failure (klass))
3860 while ((method = mono_class_get_methods (klass, &iter))) {
3862 if (method->slot != -1) {
3863 g_assert (method->slot < nslots);
3864 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3866 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3867 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3870 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3872 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3873 if (bflags & BFLAGS_Public)
3875 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3881 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3882 if (bflags & BFLAGS_Static)
3883 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3886 if (bflags & BFLAGS_Instance)
3894 if (compare_func (name, method->name))
3899 g_ptr_array_add (array, method);
3901 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3903 if (method_slots != method_slots_default)
3904 g_free (method_slots);
3909 if (method_slots != method_slots_default)
3910 g_free (method_slots);
3911 g_ptr_array_free (array, TRUE);
3913 g_assert (mono_class_has_failure (klass));
3914 mono_error_set_for_class_failure (error, klass);
3918 ICALL_EXPORT GPtrArray*
3919 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3922 GPtrArray *method_array;
3925 klass = mono_class_from_mono_type (type->type);
3926 if (type->type->byref) {
3927 return g_ptr_array_new ();
3930 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3931 mono_error_set_pending_exception (&error);
3932 return method_array;
3935 ICALL_EXPORT GPtrArray*
3936 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3938 MonoClass *startklass, *klass;
3941 gpointer iter = NULL;
3942 GPtrArray *res_array;
3945 if (type->type->byref) {
3946 return g_ptr_array_new ();
3949 klass = startklass = mono_class_from_mono_type (type->type);
3951 mono_class_setup_methods (klass);
3952 if (mono_class_has_failure (klass)) {
3953 mono_error_init (&error);
3954 mono_error_set_for_class_failure (&error, klass);
3955 mono_error_set_pending_exception (&error);
3959 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3962 while ((method = mono_class_get_methods (klass, &iter))) {
3964 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3966 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3967 if (bflags & BFLAGS_Public)
3970 if (bflags & BFLAGS_NonPublic)
3976 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3977 if (bflags & BFLAGS_Static)
3978 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3981 if (bflags & BFLAGS_Instance)
3987 g_ptr_array_add (res_array, method);
3994 property_hash (gconstpointer data)
3996 MonoProperty *prop = (MonoProperty*)data;
3998 return g_str_hash (prop->name);
4002 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4004 if (method1->slot != -1 && method1->slot == method2->slot)
4007 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4008 if (method1->is_inflated)
4009 method1 = ((MonoMethodInflated*) method1)->declaring;
4010 if (method2->is_inflated)
4011 method2 = ((MonoMethodInflated*) method2)->declaring;
4014 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4018 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4020 // Properties are hide-by-name-and-signature
4021 if (!g_str_equal (prop1->name, prop2->name))
4024 /* If we see a property in a generic method, we want to
4025 compare the generic signatures, not the inflated signatures
4026 because we might conflate two properties that were
4030 public T this[T t] { getter { return t; } } // method 1
4031 public U this[U u] { getter { return u; } } // method 2
4034 If we see int Foo<int,int>::Item[int] we need to know if
4035 the indexer came from method 1 or from method 2, and we
4036 shouldn't conflate them. (Bugzilla 36283)
4038 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4041 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4048 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4053 return method_nonpublic (accessor, start_klass);
4056 ICALL_EXPORT GPtrArray*
4057 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4060 MonoClass *startklass, *klass;
4065 int (*compare_func) (const char *s1, const char *s2) = NULL;
4067 GHashTable *properties = NULL;
4068 GPtrArray *res_array;
4070 if (type->type->byref) {
4071 return g_ptr_array_new ();
4074 mono_error_init (&error);
4076 klass = startklass = mono_class_from_mono_type (type->type);
4078 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4080 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4082 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4084 mono_class_setup_methods (klass);
4085 mono_class_setup_vtable (klass);
4086 if (mono_class_has_failure (klass)) {
4087 mono_error_set_for_class_failure (&error, klass);
4092 while ((prop = mono_class_get_properties (klass, &iter))) {
4098 flags = method->flags;
4101 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4102 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4103 if (bflags & BFLAGS_Public)
4105 } else if (bflags & BFLAGS_NonPublic) {
4106 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4107 property_accessor_nonpublic(prop->set, startklass == klass)) {
4114 if (flags & METHOD_ATTRIBUTE_STATIC) {
4115 if (bflags & BFLAGS_Static)
4116 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4119 if (bflags & BFLAGS_Instance)
4127 if (propname != NULL && compare_func (propname, prop->name))
4130 if (g_hash_table_lookup (properties, prop))
4133 g_ptr_array_add (res_array, prop);
4135 g_hash_table_insert (properties, prop, prop);
4137 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4140 g_hash_table_destroy (properties);
4147 g_hash_table_destroy (properties);
4148 g_ptr_array_free (res_array, TRUE);
4150 mono_error_set_pending_exception (&error);
4156 event_hash (gconstpointer data)
4158 MonoEvent *event = (MonoEvent*)data;
4160 return g_str_hash (event->name);
4164 event_equal (MonoEvent *event1, MonoEvent *event2)
4166 // Events are hide-by-name
4167 return g_str_equal (event1->name, event2->name);
4170 ICALL_EXPORT GPtrArray*
4171 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4174 MonoClass *startklass, *klass;
4179 int (*compare_func) (const char *s1, const char *s2) = NULL;
4180 GHashTable *events = NULL;
4181 GPtrArray *res_array;
4183 if (type->type->byref) {
4184 return g_ptr_array_new ();
4187 mono_error_init (&error);
4189 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4191 res_array = g_ptr_array_sized_new (4);
4193 klass = startklass = mono_class_from_mono_type (type->type);
4195 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4197 mono_class_setup_methods (klass);
4198 mono_class_setup_vtable (klass);
4199 if (mono_class_has_failure (klass)) {
4200 mono_error_set_for_class_failure (&error, klass);
4205 while ((event = mono_class_get_events (klass, &iter))) {
4207 method = event->add;
4209 method = event->remove;
4211 method = event->raise;
4213 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4214 if (bflags & BFLAGS_Public)
4216 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4217 if (bflags & BFLAGS_NonPublic)
4222 if (bflags & BFLAGS_NonPublic)
4228 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4229 if (bflags & BFLAGS_Static)
4230 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4233 if (bflags & BFLAGS_Instance)
4238 if (bflags & BFLAGS_Instance)
4243 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4246 if (g_hash_table_lookup (events, event))
4249 g_ptr_array_add (res_array, event);
4251 g_hash_table_insert (events, event, event);
4253 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4256 g_hash_table_destroy (events);
4262 g_hash_table_destroy (events);
4264 g_ptr_array_free (res_array, TRUE);
4266 mono_error_set_pending_exception (&error);
4270 ICALL_EXPORT GPtrArray *
4271 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4277 GPtrArray *res_array;
4279 if (type->type->byref) {
4280 return g_ptr_array_new ();
4283 klass = mono_class_from_mono_type (type->type);
4286 * If a nested type is generic, return its generic type definition.
4287 * Note that this means that the return value is essentially the set
4288 * of nested types of the generic type definition of @klass.
4290 * A note in MSDN claims that a generic type definition can have
4291 * nested types that aren't generic. In any case, the container of that
4292 * nested type would be the generic type definition.
4294 if (mono_class_is_ginst (klass))
4295 klass = mono_class_get_generic_class (klass)->container_class;
4297 res_array = g_ptr_array_new ();
4300 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4302 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4303 if (bflags & BFLAGS_Public)
4306 if (bflags & BFLAGS_NonPublic)
4312 if (str != NULL && strcmp (nested->name, str))
4315 g_ptr_array_add (res_array, &nested->byval_arg);
4322 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4324 HANDLE_FUNCTION_ENTER ();
4325 mono_error_init (error);
4326 MonoType *type = NULL;
4327 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4328 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4329 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4330 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4331 HANDLE_FUNCTION_RETURN_VAL (type);
4335 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4337 HANDLE_FUNCTION_ENTER ();
4338 mono_error_init (error);
4339 MonoType *type = NULL;
4340 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4341 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4342 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4343 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4344 HANDLE_FUNCTION_RETURN_VAL (type);
4347 ICALL_EXPORT MonoReflectionTypeHandle
4348 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4350 mono_error_init (error);
4352 MonoTypeNameParse info;
4353 gboolean type_resolve;
4355 /* On MS.NET, this does not fire a TypeResolve event */
4356 type_resolve = TRUE;
4357 char *str = mono_string_handle_to_utf8 (name, error);
4361 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4362 if (!mono_reflection_parse_type (str, &info)) {
4364 mono_reflection_free_type_info (&info);
4366 mono_error_set_argument (error, "name", "failed to parse the type");
4369 /*g_print ("failed parse\n");*/
4370 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4373 if (info.assembly.name) {
4375 mono_reflection_free_type_info (&info);
4377 /* 1.0 and 2.0 throw different exceptions */
4378 if (mono_defaults.generic_ilist_class)
4379 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4381 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4384 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4387 MonoType *type = NULL;
4388 if (!MONO_HANDLE_IS_NULL (module)) {
4389 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4391 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4392 if (!is_ok (error)) {
4394 mono_reflection_free_type_info (&info);
4400 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4401 if (assembly_is_dynamic (assembly)) {
4402 /* Enumerate all modules */
4403 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4404 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4407 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4408 MONO_HANDLE_GET (modules, abuilder, modules);
4409 if (!MONO_HANDLE_IS_NULL (modules)) {
4410 int n = mono_array_handle_length (modules);
4411 for (i = 0; i < n; ++i) {
4412 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4413 if (!is_ok (error)) {
4415 mono_reflection_free_type_info (&info);
4423 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4424 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4425 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4426 int n = mono_array_handle_length (loaded_modules);
4427 for (i = 0; i < n; ++i) {
4428 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4430 if (!is_ok (error)) {
4432 mono_reflection_free_type_info (&info);
4441 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4442 if (!is_ok (error)) {
4444 mono_reflection_free_type_info (&info);
4450 mono_reflection_free_type_info (&info);
4454 MonoError inner_error;
4455 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4456 mono_error_assert_ok (&inner_error);
4457 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4458 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4459 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4463 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4466 if (type->type == MONO_TYPE_CLASS) {
4467 MonoClass *klass = mono_type_get_class (type);
4469 /* need to report exceptions ? */
4470 if (throwOnError && mono_class_has_failure (klass)) {
4471 /* report SecurityException (or others) that occured when loading the assembly */
4472 mono_error_set_for_class_failure (error, klass);
4477 /* g_print ("got it\n"); */
4478 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4480 g_assert (!is_ok (error));
4481 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4485 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4488 gchar *shadow_ini_file;
4491 /* Check for shadow-copied assembly */
4492 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4493 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4495 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4496 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4502 g_free (shadow_ini_file);
4503 if (content != NULL) {
4506 *filename = content;
4513 ICALL_EXPORT MonoStringHandle
4514 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4516 mono_error_init (error);
4517 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4518 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4522 if (g_path_is_absolute (mass->image->name)) {
4523 absolute = g_strdup (mass->image->name);
4524 dirname = g_path_get_dirname (absolute);
4526 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4527 dirname = g_strdup (mass->basedir);
4530 replace_shadow_path (domain, dirname, &absolute);
4533 mono_icall_make_platform_path (absolute);
4537 uri = g_filename_to_uri (absolute, NULL, NULL);
4539 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4540 uri = g_strconcat (prepend, absolute, NULL);
4545 MonoStringHandle res;
4547 res = mono_string_new_handle (domain, uri, error);
4550 res = MONO_HANDLE_NEW (MonoString, NULL);
4555 ICALL_EXPORT MonoBoolean
4556 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4558 mono_error_init (error);
4559 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4561 return mass->in_gac;
4564 ICALL_EXPORT MonoReflectionAssemblyHandle
4565 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4568 MonoImageOpenStatus status;
4569 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4571 name = mono_string_handle_to_utf8 (mname, error);
4574 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4580 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4585 ICALL_EXPORT MonoStringHandle
4586 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4588 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4589 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4590 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4593 ICALL_EXPORT MonoBoolean
4594 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4596 mono_error_init (error);
4597 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4598 return assembly->ref_only;
4601 ICALL_EXPORT MonoStringHandle
4602 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4604 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4605 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4607 return mono_string_new_handle (domain, assembly->image->version, error);
4610 ICALL_EXPORT MonoReflectionMethodHandle
4611 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4613 mono_error_init (error);
4614 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4615 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4618 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4619 guint32 token = mono_image_get_entry_point (assembly->image);
4623 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4627 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4632 ICALL_EXPORT MonoReflectionModuleHandle
4633 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4635 mono_error_init (error);
4636 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4637 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4638 return mono_module_get_object_handle (domain, a->image, error);
4642 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4644 HANDLE_FUNCTION_ENTER ();
4645 mono_error_init (error);
4646 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4647 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4650 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4652 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4655 ICALL_EXPORT MonoArrayHandle
4656 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4658 mono_error_init (error);
4659 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4660 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4661 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4662 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4667 for (i = 0; i < table->rows; ++i) {
4668 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4673 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4676 ICALL_EXPORT MonoStringHandle
4677 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4679 char *guid = mono_runtime_get_aotid ();
4682 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4687 static MonoAssemblyName*
4688 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4690 mono_error_init (error);
4691 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4693 mono_assembly_get_assemblyref (image, i, aname);
4694 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4695 /* name and culture are pointers into the image tables, but we need
4696 * real malloc'd strings (so that we can g_free() them later from
4697 * Mono.RuntimeMarshal.FreeAssemblyName) */
4698 aname->name = g_strdup (aname->name);
4699 aname->culture = g_strdup (aname->culture);
4700 /* Don't need the hash value in managed */
4701 aname->hash_value = NULL;
4702 aname->hash_len = 0;
4703 g_assert (aname->public_key == NULL);
4705 /* note: this function doesn't return the codebase on purpose (i.e. it can
4706 be used under partial trust as path information isn't present). */
4710 ICALL_EXPORT GPtrArray*
4711 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4713 mono_error_init (error);
4714 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4715 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4716 MonoImage *image = ass->image;
4718 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4719 int count = t->rows;
4721 GPtrArray *result = g_ptr_array_sized_new (count);
4723 for (int i = 0; i < count; i++) {
4724 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4727 g_ptr_array_add (result, aname);
4732 /* move this in some file in mono/util/ */
4734 g_concat_dir_and_file (const char *dir, const char *file)
4736 g_return_val_if_fail (dir != NULL, NULL);
4737 g_return_val_if_fail (file != NULL, NULL);
4740 * If the directory name doesn't have a / on the end, we need
4741 * to add one so we get a proper path to the file
4743 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4744 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4746 return g_strconcat (dir, file, NULL);
4750 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4752 mono_error_init (error);
4753 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4754 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4755 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4757 guint32 cols [MONO_MANIFEST_SIZE];
4758 guint32 impl, file_idx;
4762 char *n = mono_string_handle_to_utf8 (name, error);
4763 return_val_if_nok (error, NULL);
4765 for (i = 0; i < table->rows; ++i) {
4766 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4767 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4768 if (strcmp (val, n) == 0)
4772 if (i == table->rows)
4775 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4778 * this code should only be called after obtaining the
4779 * ResourceInfo and handling the other cases.
4781 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4782 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4784 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4785 if (!is_ok (error) || !module)
4789 module = assembly->image;
4792 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4795 MONO_HANDLE_ASSIGN (ref_module, rm);
4797 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4801 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4803 HANDLE_FUNCTION_ENTER ();
4804 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4805 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4806 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4808 guint32 cols [MONO_MANIFEST_SIZE];
4809 guint32 file_cols [MONO_FILE_SIZE];
4813 gboolean result = FALSE;
4815 n = mono_string_handle_to_utf8 (name, error);
4819 for (i = 0; i < table->rows; ++i) {
4820 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4821 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4822 if (strcmp (val, n) == 0)
4826 if (i == table->rows)
4829 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4830 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4833 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4834 case MONO_IMPLEMENTATION_FILE:
4835 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4836 table = &assembly->image->tables [MONO_TABLE_FILE];
4837 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4838 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4839 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4840 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4841 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4843 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4846 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4847 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4848 mono_assembly_load_reference (assembly->image, i - 1);
4849 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4850 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4853 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4856 MONO_HANDLE_SET (info, assembly, assm_obj);
4858 /* Obtain info recursively */
4859 get_manifest_resource_info_internal (assm_obj, name, info, error);
4862 guint32 location = MONO_HANDLE_GETVAL (info, location);
4863 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4864 MONO_HANDLE_SETVAL (info, location, guint32, location);
4867 case MONO_IMPLEMENTATION_EXP_TYPE:
4868 g_assert_not_reached ();
4875 HANDLE_FUNCTION_RETURN_VAL (result);
4878 ICALL_EXPORT gboolean
4879 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4881 mono_error_init (error);
4882 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4886 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4888 HANDLE_FUNCTION_ENTER();
4889 mono_error_init (error);
4890 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4891 char *n = g_concat_dir_and_file (assembly->basedir, val);
4892 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4896 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4898 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4901 ICALL_EXPORT MonoObjectHandle
4902 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4904 mono_error_init (error);
4905 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4906 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4907 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4910 /* check hash if needed */
4911 if (!MONO_HANDLE_IS_NULL(name)) {
4912 char *n = mono_string_handle_to_utf8 (name, error);
4916 for (i = 0; i < table->rows; ++i) {
4917 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4918 if (strcmp (val, n) == 0) {
4920 n = g_concat_dir_and_file (assembly->basedir, val);
4921 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4925 return MONO_HANDLE_CAST (MonoObject, fn);
4933 for (i = 0; i < table->rows; ++i) {
4934 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4938 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4943 for (i = 0; i < table->rows; ++i) {
4944 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4945 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4950 return MONO_HANDLE_CAST (MonoObject, result);
4956 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4958 HANDLE_FUNCTION_ENTER ();
4959 mono_error_init (error);
4961 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4965 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4970 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4974 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4976 HANDLE_FUNCTION_ENTER ();
4977 mono_error_init (error);
4979 guint32 cols [MONO_FILE_SIZE];
4980 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4981 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4982 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4985 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4987 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4991 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4992 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4995 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
4998 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5002 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5005 ICALL_EXPORT MonoArrayHandle
5006 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5008 mono_error_init (error);
5009 MonoDomain *domain = mono_domain_get();
5010 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5012 int i, j, file_count = 0;
5013 MonoImage **modules;
5014 guint32 module_count, real_module_count;
5015 MonoTableInfo *table;
5016 MonoImage *image = assembly->image;
5018 g_assert (image != NULL);
5019 g_assert (!assembly_is_dynamic (assembly));
5021 table = &image->tables [MONO_TABLE_FILE];
5022 file_count = table->rows;
5024 modules = image->modules;
5025 module_count = image->module_count;
5027 real_module_count = 0;
5028 for (i = 0; i < module_count; ++i)
5030 real_module_count ++;
5032 klass = mono_class_get_module_class ();
5033 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5037 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5041 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5044 for (i = 0; i < module_count; ++i)
5045 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5048 for (i = 0; i < file_count; ++i, ++j) {
5049 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5055 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5058 ICALL_EXPORT MonoReflectionMethodHandle
5059 ves_icall_GetCurrentMethod (MonoError *error)
5061 mono_error_init (error);
5063 MonoMethod *m = mono_method_get_last_managed ();
5066 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5067 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5070 while (m->is_inflated)
5071 m = ((MonoMethodInflated*)m)->declaring;
5073 return mono_method_get_object_handle (mono_domain_get (), m, NULL, error);
5078 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5081 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5084 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5085 //method is inflated, we should inflate it on the other class
5086 MonoGenericContext ctx;
5087 ctx.method_inst = inflated->context.method_inst;
5088 ctx.class_inst = inflated->context.class_inst;
5089 if (mono_class_is_ginst (klass))
5090 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5091 else if (mono_class_is_gtd (klass))
5092 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5093 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5094 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5098 mono_class_setup_methods (method->klass);
5099 if (mono_class_has_failure (method->klass))
5101 int mcount = mono_class_get_method_count (method->klass);
5102 for (i = 0; i < mcount; ++i) {
5103 if (method->klass->methods [i] == method) {
5108 mono_class_setup_methods (klass);
5109 if (mono_class_has_failure (klass))
5111 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5112 return klass->methods [offset];
5115 ICALL_EXPORT MonoReflectionMethodHandle
5116 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check, MonoError *error)
5118 mono_error_init (error);
5120 if (type && generic_check) {
5121 klass = mono_class_from_mono_type (type);
5122 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5123 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5125 if (method->klass != klass) {
5126 method = mono_method_get_equivalent_method (method, klass);
5128 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5131 klass = mono_class_from_mono_type (type);
5133 klass = method->klass;
5134 return mono_method_get_object_handle (mono_domain_get (), method, klass, error);
5137 ICALL_EXPORT MonoReflectionMethodBodyHandle
5138 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method, MonoError *error)
5140 mono_error_init (error);
5141 return mono_method_body_get_object_handle (mono_domain_get (), method, error);
5144 ICALL_EXPORT MonoReflectionAssemblyHandle
5145 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5147 mono_error_init (error);
5149 MonoMethod *dest = NULL;
5150 mono_stack_walk_no_il (get_executing, &dest);
5152 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5156 ICALL_EXPORT MonoReflectionAssemblyHandle
5157 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5159 mono_error_init (error);
5161 MonoDomain* domain = mono_domain_get ();
5163 if (!domain->entry_assembly)
5164 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5166 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5169 ICALL_EXPORT MonoReflectionAssemblyHandle
5170 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5172 mono_error_init (error);
5177 mono_stack_walk_no_il (get_executing, &dest);
5179 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5183 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5184 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5186 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5189 ICALL_EXPORT MonoStringHandle
5190 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5191 gboolean assembly_qualified, MonoError *error)
5193 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5194 MonoType *type = MONO_HANDLE_RAW (object)->type;
5195 MonoTypeNameFormat format;
5196 MonoStringHandle res;
5200 format = assembly_qualified ?
5201 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5202 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5204 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5206 name = mono_type_get_name_full (type, format);
5208 return NULL_HANDLE_STRING;
5210 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5212 return NULL_HANDLE_STRING;
5215 res = mono_string_new_handle (domain, name, error);
5222 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5225 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5227 mono_class_init_checked (klass, &error);
5228 mono_error_set_pending_exception (&error);
5229 return mono_security_core_clr_class_level (klass);
5233 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5235 MonoClassField *field = rfield->field;
5236 return mono_security_core_clr_field_level (field, TRUE);
5240 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5242 MonoMethod *method = rfield->method;
5243 return mono_security_core_clr_method_level (method, TRUE);
5246 ICALL_EXPORT MonoStringHandle
5247 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5249 mono_error_init (error);
5250 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5251 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5254 name = mono_stringify_assembly_name (&mass->aname);
5255 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5260 ICALL_EXPORT MonoAssemblyName *
5261 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5263 return &mass->aname;
5267 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5270 MonoImageOpenStatus status = MONO_IMAGE_OK;
5271 char *codebase = NULL;
5276 mono_error_init (error);
5278 filename = mono_string_handle_to_utf8 (fname, error);
5279 return_if_nok (error);
5281 dirname = g_path_get_dirname (filename);
5282 replace_shadow_path (mono_domain_get (), dirname, &filename);
5285 image = mono_image_open (filename, &status);
5288 if (status == MONO_IMAGE_IMAGE_INVALID)
5289 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5291 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5296 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5298 mono_image_close (image);
5300 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5304 if (filename != NULL && *filename != '\0') {
5307 codebase = g_strdup (filename);
5309 mono_icall_make_platform_path (codebase);
5311 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5313 result = g_strconcat (prepend, codebase, NULL);
5317 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5320 mono_image_close (image);
5324 ICALL_EXPORT MonoBoolean
5325 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5326 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5328 mono_error_init (error);
5329 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5330 MonoBoolean result = FALSE;
5331 MonoDeclSecurityEntry entry;
5333 /* SecurityAction.RequestMinimum */
5334 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5335 *minimum = entry.blob;
5336 *minLength = entry.size;
5339 /* SecurityAction.RequestOptional */
5340 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5341 *optional = entry.blob;
5342 *optLength = entry.size;
5345 /* SecurityAction.RequestRefuse */
5346 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5347 *refused = entry.blob;
5348 *refLength = entry.size;
5356 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5358 guint32 attrs, visibility;
5360 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5361 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5362 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5365 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5371 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5373 mono_error_init (error);
5374 HANDLE_FUNCTION_ENTER ();
5375 MonoError klass_error;
5376 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5379 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5380 return_if_nok (error);
5382 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5384 MonoException *ex = mono_error_convert_to_exception (error);
5385 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5387 HANDLE_FUNCTION_RETURN ();
5390 static MonoArrayHandle
5391 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5393 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5396 mono_error_init (error);
5398 /* we start the count from 1 because we skip the special type <Module> */
5401 for (i = 1; i < tdef->rows; ++i) {
5402 if (mono_module_type_is_visible (tdef, image, i + 1))
5406 count = tdef->rows - 1;
5408 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5409 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5410 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5411 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5413 for (i = 1; i < tdef->rows; ++i) {
5414 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5415 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5416 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5425 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5427 HANDLE_FUNCTION_ENTER ();
5428 mono_error_init (error);
5429 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5430 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5434 /* Append the new types to the end of the array */
5435 if (mono_array_handle_length (res2) > 0) {
5438 len1 = mono_array_handle_length (res);
5439 len2 = mono_array_handle_length (res2);
5441 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5445 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5446 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5447 MONO_HANDLE_ASSIGN (res, res3);
5449 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5453 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5454 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5455 MONO_HANDLE_ASSIGN (exceptions, ex3);
5458 HANDLE_FUNCTION_RETURN ();
5462 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5464 HANDLE_FUNCTION_ENTER ();
5465 MonoError unboxed_error;
5466 mono_error_init (&unboxed_error);
5467 mono_error_set_for_class_failure (&unboxed_error, klass);
5469 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5470 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5471 HANDLE_FUNCTION_RETURN ();
5474 ICALL_EXPORT MonoArrayHandle
5475 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5477 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5480 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5481 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5483 g_assert (!assembly_is_dynamic (assembly));
5484 MonoImage *image = assembly->image;
5485 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5486 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5487 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5489 /* Append data from all modules in the assembly */
5490 for (i = 0; i < table->rows; ++i) {
5491 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5492 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5493 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5496 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5497 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5502 /* the ReflectionTypeLoadException must have all the types (Types property),
5503 * NULL replacing types which throws an exception. The LoaderException must
5504 * contain all exceptions for NULL items.
5507 int len = mono_array_handle_length (res);
5511 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5512 for (i = 0; i < len; i++) {
5513 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5515 if (!MONO_HANDLE_IS_NULL (t)) {
5516 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5517 if ((klass != NULL) && mono_class_has_failure (klass)) {
5518 /* keep the class in the list */
5519 list = g_list_append (list, klass);
5520 /* and replace Type with NULL */
5521 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5528 if (list || ex_count) {
5530 int j, length = g_list_length (list) + ex_count;
5532 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5533 if (!is_ok (error)) {
5535 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5537 /* Types for which mono_class_get_checked () succeeded */
5538 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5539 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5540 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5542 /* Types for which it don't */
5543 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5544 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5545 if (!MONO_HANDLE_IS_NULL (exc)) {
5546 g_assert (i < length);
5547 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5554 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5555 if (!is_ok (error)) {
5556 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5558 mono_error_set_exception_handle (error, exc);
5559 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5566 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5568 mono_assembly_name_free (aname);
5573 ICALL_EXPORT gboolean
5574 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5576 *is_version_definited = *is_token_defined = FALSE;
5578 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5581 ICALL_EXPORT MonoReflectionTypeHandle
5582 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5584 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5585 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5590 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5592 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5593 /* These images do not have a global type */
5596 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5600 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5606 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5608 /*if (module->image)
5609 mono_image_close (module->image);*/
5612 ICALL_EXPORT MonoStringHandle
5613 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5615 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5616 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5619 return mono_string_new_handle (domain, image->guid, error);
5623 static inline gpointer
5624 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5626 return (gpointer) (-1);
5628 #endif /* HOST_WIN32 */
5630 ICALL_EXPORT gpointer
5631 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5633 return mono_icall_module_get_hinstance (module);
5637 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5639 if (image_is_dynamic (image)) {
5640 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5641 *pe_kind = dyn->pe_kind;
5642 *machine = dyn->machine;
5645 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5646 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5651 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5653 return (image->md_version_major << 16) | (image->md_version_minor);
5656 ICALL_EXPORT MonoArrayHandle
5657 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5659 mono_error_init (error);
5661 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5662 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5665 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5668 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5669 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5670 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5672 int n = mono_array_handle_length (exceptions);
5673 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5674 for (int i = 0; i < n; ++i) {
5675 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5676 if (!MONO_HANDLE_IS_NULL (ex)) {
5677 mono_error_set_exception_handle (error, ex);
5678 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5686 mono_memberref_is_method (MonoImage *image, guint32 token)
5688 if (!image_is_dynamic (image)) {
5689 guint32 cols [MONO_MEMBERREF_SIZE];
5691 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5692 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5693 mono_metadata_decode_blob_size (sig, &sig);
5694 return (*sig != 0x6);
5697 MonoClass *handle_class;
5699 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5700 mono_error_cleanup (&error); /* just probing, ignore error */
5704 return mono_defaults.methodhandle_class == handle_class;
5708 static MonoGenericInst *
5709 get_generic_inst_from_array_handle (MonoArrayHandle type_args)
5711 int type_argc = mono_array_handle_length (type_args);
5712 int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
5714 MonoGenericInst *ginst = (MonoGenericInst *)g_alloca (size);
5715 memset (ginst, 0, sizeof (MonoGenericInst));
5716 ginst->type_argc = type_argc;
5717 for (int i = 0; i < type_argc; i++) {
5718 MONO_HANDLE_ARRAY_GETVAL (ginst->type_argv[i], type_args, MonoType*, i);
5720 ginst->is_open = FALSE;
5721 for (int i = 0; i < type_argc; i++) {
5722 if (mono_class_is_open_constructed_type (ginst->type_argv[i])) {
5723 ginst->is_open = TRUE;
5728 return mono_metadata_get_canonical_generic_inst (ginst);
5732 init_generic_context_from_args_handles (MonoGenericContext *context, MonoArrayHandle type_args, MonoArrayHandle method_args)
5734 if (!MONO_HANDLE_IS_NULL (type_args)) {
5735 context->class_inst = get_generic_inst_from_array_handle (type_args);
5737 context->class_inst = NULL;
5739 if (!MONO_HANDLE_IS_NULL (method_args)) {
5740 context->method_inst = get_generic_inst_from_array_handle (method_args);
5742 context->method_inst = NULL;
5748 module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5750 HANDLE_FUNCTION_ENTER ();
5751 mono_error_init (error);
5752 MonoType *result = NULL;
5754 int table = mono_metadata_token_table (token);
5755 int index = mono_metadata_token_index (token);
5756 MonoGenericContext context;
5758 *resolve_error = ResolveTokenError_Other;
5760 /* Validate token */
5761 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5762 (table != MONO_TABLE_TYPESPEC)) {
5763 *resolve_error = ResolveTokenError_BadTable;
5767 if (image_is_dynamic (image)) {
5768 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5769 MonoError inner_error;
5770 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5771 mono_error_cleanup (&inner_error);
5772 result = klass ? &klass->byval_arg : NULL;
5776 init_generic_context_from_args_handles (&context, type_args, method_args);
5777 MonoError inner_error;
5778 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5779 mono_error_cleanup (&inner_error);
5780 result = klass ? &klass->byval_arg : NULL;
5784 if ((index <= 0) || (index > image->tables [table].rows)) {
5785 *resolve_error = ResolveTokenError_OutOfRange;
5789 init_generic_context_from_args_handles (&context, type_args, method_args);
5790 klass = mono_class_get_checked (image, token, error);
5792 klass = mono_class_inflate_generic_class_checked (klass, &context, error);
5797 result = &klass->byval_arg;
5799 HANDLE_FUNCTION_RETURN_VAL (result);
5802 ICALL_EXPORT MonoType*
5803 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5805 return module_resolve_type_token (image, token, type_args, method_args, resolve_error, error);
5809 module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5811 HANDLE_FUNCTION_ENTER ();
5812 mono_error_init (error);
5813 MonoMethod *method = NULL;
5814 int table = mono_metadata_token_table (token);
5815 int index = mono_metadata_token_index (token);
5816 MonoGenericContext context;
5818 *resolve_error = ResolveTokenError_Other;
5820 /* Validate token */
5821 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5822 (table != MONO_TABLE_MEMBERREF)) {
5823 *resolve_error = ResolveTokenError_BadTable;
5827 if (image_is_dynamic (image)) {
5828 if (table == MONO_TABLE_METHOD) {
5829 MonoError inner_error;
5830 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5831 mono_error_cleanup (&inner_error);
5835 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5836 *resolve_error = ResolveTokenError_BadTable;
5840 init_generic_context_from_args_handles (&context, type_args, method_args);
5841 MonoError inner_error;
5842 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5843 mono_error_cleanup (&inner_error);
5847 if ((index <= 0) || (index > image->tables [table].rows)) {
5848 *resolve_error = ResolveTokenError_OutOfRange;
5851 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5852 *resolve_error = ResolveTokenError_BadTable;
5856 init_generic_context_from_args_handles (&context, type_args, method_args);
5857 method = mono_get_method_checked (image, token, NULL, &context, error);
5860 HANDLE_FUNCTION_RETURN_VAL (method);
5863 ICALL_EXPORT MonoMethod*
5864 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5866 return module_resolve_method_token (image, token, type_args, method_args, resolve_error, error);
5869 ICALL_EXPORT MonoString*
5870 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5873 int index = mono_metadata_token_index (token);
5875 *resolve_error = ResolveTokenError_Other;
5877 /* Validate token */
5878 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5879 *resolve_error = ResolveTokenError_BadTable;
5883 if (image_is_dynamic (image)) {
5884 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5885 mono_error_cleanup (&error);
5889 if ((index <= 0) || (index >= image->heap_us.size)) {
5890 *resolve_error = ResolveTokenError_OutOfRange;
5894 /* FIXME: What to do if the index points into the middle of a string ? */
5896 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5897 mono_error_set_pending_exception (&error);
5901 static MonoClassField*
5902 module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5904 HANDLE_FUNCTION_ENTER ();
5906 int table = mono_metadata_token_table (token);
5907 int index = mono_metadata_token_index (token);
5908 MonoGenericContext context;
5909 MonoClassField *field = NULL;
5911 mono_error_init (error);
5912 *resolve_error = ResolveTokenError_Other;
5914 /* Validate token */
5915 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5916 *resolve_error = ResolveTokenError_BadTable;
5920 if (image_is_dynamic (image)) {
5921 if (table == MONO_TABLE_FIELD) {
5922 MonoError inner_error;
5923 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5924 mono_error_cleanup (&inner_error);
5928 if (mono_memberref_is_method (image, token)) {
5929 *resolve_error = ResolveTokenError_BadTable;
5933 init_generic_context_from_args_handles (&context, type_args, method_args);
5934 MonoError inner_error;
5935 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5936 mono_error_cleanup (&inner_error);
5940 if ((index <= 0) || (index > image->tables [table].rows)) {
5941 *resolve_error = ResolveTokenError_OutOfRange;
5944 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5945 *resolve_error = ResolveTokenError_BadTable;
5949 init_generic_context_from_args_handles (&context, type_args, method_args);
5950 field = mono_field_from_token_checked (image, token, &klass, &context, error);
5953 HANDLE_FUNCTION_RETURN_VAL (field);
5956 ICALL_EXPORT MonoClassField*
5957 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5959 return module_resolve_field_token (image, token, type_args, method_args, resolve_error, error);
5962 ICALL_EXPORT MonoObjectHandle
5963 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *error, MonoError *merror)
5965 int table = mono_metadata_token_table (token);
5967 mono_error_init (merror);
5968 *error = ResolveTokenError_Other;
5971 case MONO_TABLE_TYPEDEF:
5972 case MONO_TABLE_TYPEREF:
5973 case MONO_TABLE_TYPESPEC: {
5974 MonoType *t = module_resolve_type_token (image, token, type_args, method_args, error, merror);
5976 return MONO_HANDLE_CAST (MonoObject, mono_type_get_object_handle (mono_domain_get (), t, merror));
5981 case MONO_TABLE_METHOD:
5982 case MONO_TABLE_METHODSPEC: {
5983 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
5985 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
5989 case MONO_TABLE_FIELD: {
5990 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
5992 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
5997 case MONO_TABLE_MEMBERREF:
5998 if (mono_memberref_is_method (image, token)) {
5999 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
6001 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
6006 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
6008 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6016 *error = ResolveTokenError_BadTable;
6022 ICALL_EXPORT MonoArrayHandle
6023 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error, MonoError *error)
6025 mono_error_init (error);
6026 int table = mono_metadata_token_table (token);
6027 int idx = mono_metadata_token_index (token);
6028 MonoTableInfo *tables = image->tables;
6032 *resolve_error = ResolveTokenError_OutOfRange;
6034 /* FIXME: Support other tables ? */
6035 if (table != MONO_TABLE_STANDALONESIG)
6036 return MONO_HANDLE_CAST (MonoArray, NULL);
6038 if (image_is_dynamic (image))
6039 return MONO_HANDLE_CAST (MonoArray, NULL);
6041 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6042 return MONO_HANDLE_CAST (MonoArray, NULL);
6044 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6046 ptr = mono_metadata_blob_heap (image, sig);
6047 len = mono_metadata_decode_blob_size (ptr, &ptr);
6049 MonoArrayHandle res = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, len, error);
6051 return MONO_HANDLE_CAST (MonoArray, NULL);
6053 gpointer array_base = MONO_ARRAY_HANDLE_PIN (res, guint8, 0, &h);
6054 memcpy (array_base, ptr, len);
6055 mono_gchandle_free (h);
6059 ICALL_EXPORT MonoBoolean
6060 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionTypeHandle ref_type, MonoError *error)
6062 mono_error_init (error);
6063 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6065 MonoBoolean res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6071 check_for_invalid_type (MonoClass *klass, MonoError *error)
6075 mono_error_init (error);
6077 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6080 name = mono_type_get_full_name (klass);
6081 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6083 ICALL_EXPORT MonoReflectionType *
6084 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6087 MonoReflectionType *ret;
6088 MonoClass *klass, *aklass;
6090 klass = mono_class_from_mono_type (type->type);
6091 check_for_invalid_type (klass, &error);
6092 if (mono_error_set_pending_exception (&error))
6095 if (rank == 0) //single dimentional array
6096 aklass = mono_array_class_get (klass, 1);
6098 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6100 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6101 mono_error_set_pending_exception (&error);
6106 ICALL_EXPORT MonoReflectionType *
6107 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6110 MonoReflectionType *ret;
6113 klass = mono_class_from_mono_type (type->type);
6114 mono_class_init_checked (klass, &error);
6115 if (mono_error_set_pending_exception (&error))
6118 check_for_invalid_type (klass, &error);
6119 if (mono_error_set_pending_exception (&error))
6122 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6123 mono_error_set_pending_exception (&error);
6128 ICALL_EXPORT MonoReflectionType *
6129 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6132 MonoReflectionType *ret;
6133 MonoClass *klass, *pklass;
6135 klass = mono_class_from_mono_type (type->type);
6136 mono_class_init_checked (klass, &error);
6137 if (mono_error_set_pending_exception (&error))
6139 check_for_invalid_type (klass, &error);
6140 if (mono_error_set_pending_exception (&error))
6143 pklass = mono_ptr_class_get (type->type);
6145 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6146 mono_error_set_pending_exception (&error);
6151 ICALL_EXPORT MonoObject *
6152 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6153 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6156 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6157 MonoObject *delegate;
6159 MonoMethod *method = info->method;
6160 MonoMethodSignature *sig = mono_method_signature(method);
6162 mono_class_init_checked (delegate_class, &error);
6163 if (mono_error_set_pending_exception (&error))
6166 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6167 /* FIXME improve this exception message */
6168 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6170 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6171 mono_error_set_pending_exception (&error);
6175 if (mono_security_core_clr_enabled ()) {
6176 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6177 if (throwOnBindFailure)
6178 mono_error_set_pending_exception (&error);
6180 mono_error_cleanup (&error);
6185 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6186 if (!method->is_inflated) {
6187 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"));
6192 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6193 if (mono_error_set_pending_exception (&error))
6196 if (method_is_dynamic (method)) {
6197 /* Creating a trampoline would leak memory */
6198 func = mono_compile_method_checked (method, &error);
6199 if (mono_error_set_pending_exception (&error))
6202 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6203 method = mono_object_get_virtual_method (target, method);
6204 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6205 if (mono_error_set_pending_exception (&error))
6207 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6210 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6211 if (mono_error_set_pending_exception (&error))
6216 ICALL_EXPORT MonoMulticastDelegate *
6217 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6220 MonoMulticastDelegate *ret;
6222 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6224 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6225 if (mono_error_set_pending_exception (&error))
6228 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6233 ICALL_EXPORT MonoReflectionMethod*
6234 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6236 MonoReflectionMethod *ret = NULL;
6238 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6239 mono_error_set_pending_exception (&error);
6245 static inline gint32
6246 mono_array_get_byte_length (MonoArray *array)
6252 klass = array->obj.vtable->klass;
6254 if (array->bounds == NULL)
6255 length = array->max_length;
6258 for (i = 0; i < klass->rank; ++ i)
6259 length *= array->bounds [i].length;
6262 switch (klass->element_class->byval_arg.type) {
6265 case MONO_TYPE_BOOLEAN:
6269 case MONO_TYPE_CHAR:
6277 return length * sizeof (gpointer);
6288 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6290 return mono_array_get_byte_length (array);
6294 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6296 return mono_array_get (array, gint8, idx);
6300 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6302 mono_array_set (array, gint8, idx, value);
6305 ICALL_EXPORT MonoBoolean
6306 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6308 guint8 *src_buf, *dest_buf;
6311 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6315 g_assert (count >= 0);
6317 /* This is called directly from the class libraries without going through the managed wrapper */
6318 MONO_CHECK_ARG_NULL (src, FALSE);
6319 MONO_CHECK_ARG_NULL (dest, FALSE);
6321 /* watch out for integer overflow */
6322 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6325 src_buf = (guint8 *)src->vector + src_offset;
6326 dest_buf = (guint8 *)dest->vector + dest_offset;
6329 memcpy (dest_buf, src_buf, count);
6331 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6336 #ifndef DISABLE_REMOTING
6337 ICALL_EXPORT MonoObjectHandle
6338 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObjectHandle this_obj, MonoStringHandle class_name, MonoError *error)
6340 mono_error_init (error);
6341 MonoDomain *domain = MONO_HANDLE_DOMAIN (this_obj);
6342 MonoRealProxyHandle rp = MONO_HANDLE_CAST (MonoRealProxy, this_obj);
6344 MonoObjectHandle res = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, error));
6348 MonoTransparentProxyHandle tp = MONO_HANDLE_CAST (MonoTransparentProxy, res);
6350 MONO_HANDLE_SET (tp, rp, rp);
6352 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
6353 MONO_HANDLE_GET (reftype, rp, class_to_proxy);
6354 MonoType *type = MONO_HANDLE_GETVAL (reftype, type);
6355 MonoClass *klass = mono_class_from_mono_type (type);
6357 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6358 mono_class_setup_vtable (klass);
6359 if (mono_class_has_failure (klass)) {
6360 mono_error_set_for_class_failure (error, klass);
6364 MonoObjectHandle remoting_obj = mono_object_handle_isinst (this_obj, mono_defaults.iremotingtypeinfo_class, error);
6367 MONO_HANDLE_SETVAL (tp, custom_type_info, MonoBoolean, !MONO_HANDLE_IS_NULL (remoting_obj));
6369 MonoRemoteClass *remote_class = mono_remote_class (domain, class_name, klass, error);
6372 MONO_HANDLE_SETVAL (tp, remote_class, MonoRemoteClass*, remote_class);
6374 MONO_HANDLE_SETVAL (res, vtable, MonoVTable*, mono_remote_class_vtable (domain, remote_class, rp, error));
6380 ICALL_EXPORT MonoReflectionType *
6381 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6384 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6385 mono_error_set_pending_exception (&error);
6391 /* System.Environment */
6394 ves_icall_System_Environment_get_UserName (void)
6396 /* using glib is more portable */
6397 return mono_string_new (mono_domain_get (), g_get_user_name ());
6402 mono_icall_get_machine_name (void)
6404 #if !defined(DISABLE_SOCKETS)
6408 #if defined _SC_HOST_NAME_MAX
6409 n = sysconf (_SC_HOST_NAME_MAX);
6413 buf = g_malloc (n+1);
6415 if (gethostname (buf, n) == 0){
6417 result = mono_string_new (mono_domain_get (), buf);
6424 return mono_string_new (mono_domain_get (), "mono");
6427 #endif /* !HOST_WIN32 */
6429 ICALL_EXPORT MonoString *
6430 ves_icall_System_Environment_get_MachineName (void)
6432 return mono_icall_get_machine_name ();
6437 mono_icall_get_platform (void)
6439 #if defined(__MACH__)
6442 // Notice that the value is hidden from user code, and only exposed
6443 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6444 // define and making assumptions based on Unix/128/4 values before there
6445 // was a MacOS define. Lots of code would assume that not-Unix meant
6446 // Windows, but in this case, it would be OSX.
6454 #endif /* !HOST_WIN32 */
6457 ves_icall_System_Environment_get_Platform (void)
6459 return mono_icall_get_platform ();
6463 static inline MonoString *
6464 mono_icall_get_new_line (void)
6466 return mono_string_new (mono_domain_get (), "\n");
6468 #endif /* !HOST_WIN32 */
6470 ICALL_EXPORT MonoString *
6471 ves_icall_System_Environment_get_NewLine (void)
6473 return mono_icall_get_new_line ();
6477 static inline MonoBoolean
6478 mono_icall_is_64bit_os (void)
6480 #if SIZEOF_VOID_P == 8
6483 #if defined(HAVE_SYS_UTSNAME_H)
6484 struct utsname name;
6486 if (uname (&name) >= 0) {
6487 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6493 #endif /* !HOST_WIN32 */
6495 ICALL_EXPORT MonoBoolean
6496 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6498 return mono_icall_is_64bit_os ();
6501 ICALL_EXPORT MonoStringHandle
6502 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6506 if (utf8_name == NULL)
6507 return NULL_HANDLE_STRING;
6509 value = g_getenv (utf8_name);
6512 return NULL_HANDLE_STRING;
6514 return mono_string_new_handle (mono_domain_get (), value, error);
6518 * There is no standard way to get at environ.
6521 #ifndef __MINGW32_VERSION
6522 #if defined(__APPLE__)
6523 #if defined (TARGET_OSX)
6524 /* Apple defines this in crt_externs.h but doesn't provide that header for
6525 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6526 * in fact exist on all implementations (so far)
6528 gchar ***_NSGetEnviron(void);
6529 #define environ (*_NSGetEnviron())
6531 static char *mono_environ[1] = { NULL };
6532 #define environ mono_environ
6533 #endif /* defined (TARGET_OSX) */
6541 ICALL_EXPORT MonoArray *
6542 ves_icall_System_Environment_GetCoomandLineArgs (void)
6545 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6546 mono_error_set_pending_exception (&error);
6552 mono_icall_get_environment_variable_names (void)
6562 for (e = environ; *e != 0; ++ e)
6565 domain = mono_domain_get ();
6566 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6567 if (mono_error_set_pending_exception (&error))
6571 for (e = environ; *e != 0; ++ e) {
6572 parts = g_strsplit (*e, "=", 2);
6574 str = mono_string_new (domain, *parts);
6575 mono_array_setref (names, n, str);
6585 #endif /* !HOST_WIN32 */
6587 ICALL_EXPORT MonoArray *
6588 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6590 return mono_icall_get_environment_variable_names ();
6595 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6597 gchar *utf8_name, *utf8_value;
6600 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6601 if (mono_error_set_pending_exception (&error))
6604 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6605 g_unsetenv (utf8_name);
6610 utf8_value = mono_string_to_utf8_checked (value, &error);
6611 if (!mono_error_ok (&error)) {
6613 mono_error_set_pending_exception (&error);
6616 g_setenv (utf8_name, utf8_value, TRUE);
6619 g_free (utf8_value);
6621 #endif /* !HOST_WIN32 */
6624 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6626 mono_icall_set_environment_variable (name, value);
6630 ves_icall_System_Environment_Exit (int result)
6632 mono_environment_exitcode_set (result);
6634 /* FIXME: There are some cleanup hangs that should be worked out, but
6635 * if the program is going to exit, everything will be cleaned up when
6636 * NaCl exits anyway.
6638 #ifndef __native_client__
6639 if (!mono_runtime_try_shutdown ())
6640 mono_thread_exit ();
6642 /* Suspend all managed threads since the runtime is going away */
6643 mono_thread_suspend_all_other_threads ();
6645 mono_runtime_quit ();
6648 /* we may need to do some cleanup here... */
6652 ICALL_EXPORT MonoStringHandle
6653 ves_icall_System_Environment_GetGacPath (MonoError *error)
6655 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6659 static inline MonoString *
6660 mono_icall_get_windows_folder_path (int folder)
6662 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6663 return mono_string_new (mono_domain_get (), "");
6665 #endif /* !HOST_WIN32 */
6667 ICALL_EXPORT MonoString*
6668 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6670 return mono_icall_get_windows_folder_path (folder);
6673 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6675 mono_icall_get_logical_drives (void)
6678 gunichar2 buf [256], *ptr, *dname;
6680 guint initial_size = 127, size = 128;
6683 MonoString *drivestr;
6684 MonoDomain *domain = mono_domain_get ();
6690 while (size > initial_size) {
6691 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6692 if (size > initial_size) {
6695 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6696 initial_size = size;
6710 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6711 if (mono_error_set_pending_exception (&error))
6718 while (*u16) { u16++; len ++; }
6719 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6720 if (mono_error_set_pending_exception (&error))
6723 mono_array_setref (result, ndrives++, drivestr);
6733 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6735 ICALL_EXPORT MonoArray *
6736 ves_icall_System_Environment_GetLogicalDrives (void)
6738 return mono_icall_get_logical_drives ();
6741 ICALL_EXPORT MonoString *
6742 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6745 gunichar2 volume_name [MAX_PATH + 1];
6747 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6749 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6750 mono_error_set_pending_exception (&error);
6754 ICALL_EXPORT MonoStringHandle
6755 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6757 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6760 static const char *encodings [] = {
6762 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6763 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6764 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6766 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6767 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6768 "x_unicode_2_0_utf_7",
6770 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6771 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6773 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6776 "unicodefffe", "utf_16be",
6783 * Returns the internal codepage, if the value of "int_code_page" is
6784 * 1 at entry, and we can not compute a suitable code page number,
6785 * returns the code page as a string
6787 ICALL_EXPORT MonoString*
6788 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6793 char *codepage = NULL;
6795 int want_name = *int_code_page;
6798 *int_code_page = -1;
6800 g_get_charset (&cset);
6801 c = codepage = g_strdup (cset);
6802 for (c = codepage; *c; c++){
6803 if (isascii (*c) && isalpha (*c))
6808 /* g_print ("charset: %s\n", cset); */
6810 /* handle some common aliases */
6813 for (i = 0; p != 0; ){
6816 p = encodings [++i];
6819 if (strcmp (p, codepage) == 0){
6820 *int_code_page = code;
6823 p = encodings [++i];
6826 if (strstr (codepage, "utf_8") != NULL)
6827 *int_code_page |= 0x10000000;
6830 if (want_name && *int_code_page == -1)
6831 return mono_string_new (mono_domain_get (), cset);
6836 ICALL_EXPORT MonoBoolean
6837 ves_icall_System_Environment_get_HasShutdownStarted (void)
6839 if (mono_runtime_is_shutting_down ())
6842 if (mono_domain_is_unloading (mono_domain_get ()))
6850 mono_icall_broadcast_setting_change (void)
6854 #endif /* !HOST_WIN32 */
6857 ves_icall_System_Environment_BroadcastSettingChange (void)
6859 mono_icall_broadcast_setting_change ();
6864 ves_icall_System_Environment_get_TickCount (void)
6866 /* this will overflow after ~24 days */
6867 return (gint32) (mono_msec_boottime () & 0xffffffff);
6871 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6876 #ifndef DISABLE_REMOTING
6877 ICALL_EXPORT MonoBoolean
6878 ves_icall_IsTransparentProxy (MonoObject *proxy)
6883 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6889 ICALL_EXPORT MonoReflectionMethod *
6890 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6891 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6893 MonoReflectionMethod *ret = NULL;
6898 MonoMethod **vtable;
6899 MonoMethod *res = NULL;
6901 MONO_CHECK_ARG_NULL (rtype, NULL);
6902 MONO_CHECK_ARG_NULL (rmethod, NULL);
6904 method = rmethod->method;
6905 klass = mono_class_from_mono_type (rtype->type);
6906 mono_class_init_checked (klass, &error);
6907 if (mono_error_set_pending_exception (&error))
6910 if (MONO_CLASS_IS_INTERFACE (klass))
6913 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6916 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6917 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6923 mono_class_setup_vtable (klass);
6924 vtable = klass->vtable;
6926 if (mono_class_is_interface (method->klass)) {
6927 gboolean variance_used = FALSE;
6928 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6929 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6931 res = vtable [offs + method->slot];
6933 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6936 if (method->slot != -1)
6937 res = vtable [method->slot];
6943 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6944 mono_error_set_pending_exception (&error);
6949 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6955 klass = mono_class_from_mono_type (type->type);
6956 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6957 if (!is_ok (&error)) {
6958 mono_error_set_pending_exception (&error);
6962 mono_vtable_set_is_remote (vtable, enable);
6965 #else /* DISABLE_REMOTING */
6968 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6970 g_assert_not_reached ();
6975 ICALL_EXPORT MonoObject *
6976 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6983 domain = mono_object_domain (type);
6984 klass = mono_class_from_mono_type (type->type);
6985 mono_class_init_checked (klass, &error);
6986 if (mono_error_set_pending_exception (&error))
6989 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6990 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6994 if (klass->rank >= 1) {
6995 g_assert (klass->rank == 1);
6996 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6997 mono_error_set_pending_exception (&error);
7000 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
7001 if (!is_ok (&error)) {
7002 mono_error_set_pending_exception (&error);
7005 /* Bypass remoting object creation check */
7006 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7007 mono_error_set_pending_exception (&error);
7013 ICALL_EXPORT MonoStringHandle
7014 ves_icall_System_IO_get_temp_path (MonoError *error)
7016 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7019 #ifndef PLATFORM_NO_DRIVEINFO
7020 ICALL_EXPORT MonoBoolean
7021 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7022 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7026 ULARGE_INTEGER wapi_free_bytes_avail;
7027 ULARGE_INTEGER wapi_total_number_of_bytes;
7028 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7030 *error = ERROR_SUCCESS;
7031 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7032 &wapi_total_number_of_free_bytes);
7035 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7036 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7037 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7039 *free_bytes_avail = 0;
7040 *total_number_of_bytes = 0;
7041 *total_number_of_free_bytes = 0;
7042 *error = GetLastError ();
7048 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7049 static inline guint32
7050 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7052 return GetDriveType (mono_string_chars (root_path_name));
7054 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7056 ICALL_EXPORT guint32
7057 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7059 return mono_icall_drive_info_get_drive_type (root_path_name);
7062 #endif /* PLATFORM_NO_DRIVEINFO */
7064 ICALL_EXPORT gpointer
7065 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7068 gpointer result = mono_compile_method_checked (method, &error);
7069 mono_error_set_pending_exception (&error);
7073 ICALL_EXPORT MonoString *
7074 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7079 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7081 mono_icall_make_platform_path (path);
7083 mcpath = mono_string_new (mono_domain_get (), path);
7089 /* this is an icall */
7091 get_bundled_app_config (void)
7094 const gchar *app_config;
7097 gchar *config_file_name, *config_file_path;
7098 gsize len, config_file_path_length, config_ext_length;
7101 domain = mono_domain_get ();
7102 file = domain->setup->configuration_file;
7103 if (!file || file->length == 0)
7106 // Retrieve config file and remove the extension
7107 config_file_name = mono_string_to_utf8_checked (file, &error);
7108 if (mono_error_set_pending_exception (&error))
7110 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7111 if (!config_file_path)
7112 config_file_path = config_file_name;
7114 config_file_path_length = strlen (config_file_path);
7115 config_ext_length = strlen (".config");
7116 if (config_file_path_length <= config_ext_length)
7119 len = config_file_path_length - config_ext_length;
7120 module = (gchar *)g_malloc0 (len + 1);
7121 memcpy (module, config_file_path, len);
7122 // Get the config file from the module name
7123 app_config = mono_config_string_for_assembly_file (module);
7126 if (config_file_name != config_file_path)
7127 g_free (config_file_name);
7128 g_free (config_file_path);
7133 return mono_string_new (mono_domain_get (), app_config);
7136 static MonoStringHandle
7137 get_bundled_machine_config (MonoError *error)
7139 const gchar *machine_config;
7141 machine_config = mono_get_machine_config ();
7143 if (!machine_config)
7144 return NULL_HANDLE_STRING;
7146 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7149 ICALL_EXPORT MonoStringHandle
7150 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7152 return get_bundled_machine_config (error);
7156 ICALL_EXPORT MonoStringHandle
7157 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7159 return get_bundled_machine_config (error);
7162 ICALL_EXPORT MonoStringHandle
7163 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7165 return get_bundled_machine_config (error);
7169 ICALL_EXPORT MonoString *
7170 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7175 path = g_path_get_dirname (mono_get_config_dir ());
7177 mono_icall_make_platform_path (path);
7179 ipath = mono_string_new (mono_domain_get (), path);
7185 ICALL_EXPORT gboolean
7186 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7188 mono_error_init (error);
7189 MonoPEResourceDataEntry *entry;
7192 if (!assembly || !result || !size)
7197 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7198 image = assm->image;
7199 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7203 *result = mono_image_rva_map (image, entry->rde_data_offset);
7208 *size = entry->rde_size;
7213 ICALL_EXPORT MonoBoolean
7214 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7216 return mono_is_debugger_attached ();
7219 ICALL_EXPORT MonoBoolean
7220 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7222 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7223 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7229 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7231 if (mono_get_runtime_callbacks ()->debug_log)
7232 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7237 mono_icall_write_windows_debug_string (MonoString *message)
7239 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7241 #endif /* !HOST_WIN32 */
7244 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7246 mono_icall_write_windows_debug_string (message);
7249 /* Only used for value types */
7250 ICALL_EXPORT MonoObject *
7251 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7258 domain = mono_object_domain (type);
7259 klass = mono_class_from_mono_type (type->type);
7260 mono_class_init_checked (klass, &error);
7261 if (mono_error_set_pending_exception (&error))
7264 if (mono_class_is_nullable (klass))
7265 /* No arguments -> null */
7268 result = mono_object_new_checked (domain, klass, &error);
7269 mono_error_set_pending_exception (&error);
7273 ICALL_EXPORT MonoReflectionMethod *
7274 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7276 MonoReflectionMethod *ret = NULL;
7279 MonoClass *klass, *parent;
7280 MonoGenericContext *generic_inst = NULL;
7281 MonoMethod *method = m->method;
7282 MonoMethod *result = NULL;
7285 if (method->klass == NULL)
7288 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7289 MONO_CLASS_IS_INTERFACE (method->klass) ||
7290 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7293 slot = mono_method_get_vtable_slot (method);
7297 klass = method->klass;
7298 if (mono_class_is_ginst (klass)) {
7299 generic_inst = mono_class_get_context (klass);
7300 klass = mono_class_get_generic_class (klass)->container_class;
7305 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7306 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7307 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7308 or klass is the generic container class and generic_inst is the instantiation.
7310 when we go to the parent, if the parent is an open constructed type, we need to
7311 replace the type parameters by the definitions from the generic_inst, and then take it
7312 apart again into the klass and the generic_inst.
7314 For cases like this:
7315 class C<T> : B<T, int> {
7316 public override void Foo () { ... }
7318 class B<U,V> : A<HashMap<U,V>> {
7319 public override void Foo () { ... }
7322 public virtual void Foo () { ... }
7325 if at each iteration the parent isn't open, we can skip inflating it. if at some
7326 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7329 MonoGenericContext *parent_inst = NULL;
7330 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7331 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7332 if (!mono_error_ok (&error)) {
7333 mono_error_set_pending_exception (&error);
7337 if (mono_class_is_ginst (parent)) {
7338 parent_inst = mono_class_get_context (parent);
7339 parent = mono_class_get_generic_class (parent)->container_class;
7342 mono_class_setup_vtable (parent);
7343 if (parent->vtable_size <= slot)
7346 generic_inst = parent_inst;
7349 klass = klass->parent;
7352 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7353 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7354 if (!mono_error_ok (&error)) {
7355 mono_error_set_pending_exception (&error);
7359 generic_inst = NULL;
7361 if (mono_class_is_ginst (klass)) {
7362 generic_inst = mono_class_get_context (klass);
7363 klass = mono_class_get_generic_class (klass)->container_class;
7369 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7370 if (!mono_error_ok (&error)) {
7371 mono_error_set_pending_exception (&error);
7376 if (klass == method->klass)
7379 /*This is possible if definition == FALSE.
7380 * Do it here to be really sure we don't read invalid memory.
7382 if (slot >= klass->vtable_size)
7385 mono_class_setup_vtable (klass);
7387 result = klass->vtable [slot];
7388 if (result == NULL) {
7389 /* It is an abstract method */
7390 gboolean found = FALSE;
7391 gpointer iter = NULL;
7392 while ((result = mono_class_get_methods (klass, &iter))) {
7393 if (result->slot == slot) {
7398 /* found might be FALSE if we looked in an abstract class
7399 * that doesn't override an abstract method of its
7401 * abstract class Base {
7402 * public abstract void Foo ();
7404 * abstract class Derived : Base { }
7405 * class Child : Derived {
7406 * public override void Foo () { }
7409 * if m was Child.Foo and we ask for the base method,
7410 * then we get here with klass == Derived and found == FALSE
7412 /* but it shouldn't be the case that if we're looking
7413 * for the definition and didn't find a result; the
7414 * loop above should've taken us as far as we could
7416 g_assert (!(definition && !found));
7421 g_assert (result != NULL);
7423 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7424 mono_error_set_pending_exception (&error);
7428 ICALL_EXPORT MonoString*
7429 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7431 MonoMethod *method = m->method;
7433 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7438 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7440 iter->sig = *(MonoMethodSignature**)argsp;
7442 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7443 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7446 /* FIXME: it's not documented what start is exactly... */
7450 iter->args = argsp + sizeof (gpointer);
7452 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7454 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7457 ICALL_EXPORT MonoTypedRef
7458 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7460 guint32 i, arg_size;
7464 i = iter->sig->sentinelpos + iter->next_arg;
7466 g_assert (i < iter->sig->param_count);
7468 res.type = iter->sig->params [i];
7469 res.klass = mono_class_from_mono_type (res.type);
7470 arg_size = mono_type_stack_size (res.type, &align);
7471 #if defined(__arm__) || defined(__mips__)
7472 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7474 res.value = iter->args;
7475 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7476 /* Values are stored as 8 byte register sized objects, but 'value'
7477 * is dereferenced as a pointer in other routines.
7479 res.value = (char*)res.value + 4;
7481 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7482 if (arg_size <= sizeof (gpointer)) {
7484 int padding = arg_size - mono_type_size (res.type, &dummy);
7485 res.value = (guint8*)res.value + padding;
7488 iter->args = (char*)iter->args + arg_size;
7491 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7496 ICALL_EXPORT MonoTypedRef
7497 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7499 guint32 i, arg_size;
7503 i = iter->sig->sentinelpos + iter->next_arg;
7505 g_assert (i < iter->sig->param_count);
7507 while (i < iter->sig->param_count) {
7508 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7510 res.type = iter->sig->params [i];
7511 res.klass = mono_class_from_mono_type (res.type);
7512 /* FIXME: endianess issue... */
7513 arg_size = mono_type_stack_size (res.type, &align);
7514 #if defined(__arm__) || defined(__mips__)
7515 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7517 res.value = iter->args;
7518 iter->args = (char*)iter->args + arg_size;
7520 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7523 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7531 ICALL_EXPORT MonoType*
7532 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7536 i = iter->sig->sentinelpos + iter->next_arg;
7538 g_assert (i < iter->sig->param_count);
7540 return iter->sig->params [i];
7543 ICALL_EXPORT MonoObject*
7544 mono_TypedReference_ToObject (MonoTypedRef* tref)
7547 MonoObject *result = NULL;
7548 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7549 MonoObject** objp = (MonoObject **)tref->value;
7553 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7554 mono_error_set_pending_exception (&error);
7558 ICALL_EXPORT MonoTypedRef
7559 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7562 MonoReflectionField *f;
7564 MonoType *ftype = NULL;
7568 memset (&res, 0, sizeof (res));
7571 g_assert (mono_array_length (fields) > 0);
7573 klass = target->vtable->klass;
7575 for (i = 0; i < mono_array_length (fields); ++i) {
7576 f = mono_array_get (fields, MonoReflectionField*, i);
7578 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7581 if (f->field->parent != klass) {
7582 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7586 p = (guint8*)target + f->field->offset;
7588 p += f->field->offset - sizeof (MonoObject);
7589 klass = mono_class_from_mono_type (f->field->type);
7590 ftype = f->field->type;
7594 res.klass = mono_class_from_mono_type (ftype);
7601 prelink_method (MonoMethod *method, MonoError *error)
7603 const char *exc_class, *exc_arg;
7605 mono_error_init (error);
7606 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7608 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7610 mono_error_set_exception_instance (error,
7611 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7614 /* create the wrapper, too? */
7618 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7622 prelink_method (method->method, &error);
7623 mono_error_set_pending_exception (&error);
7627 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7630 MonoClass *klass = mono_class_from_mono_type (type->type);
7632 gpointer iter = NULL;
7634 mono_class_init_checked (klass, &error);
7635 if (mono_error_set_pending_exception (&error))
7638 while ((m = mono_class_get_methods (klass, &iter))) {
7639 prelink_method (m, &error);
7640 if (mono_error_set_pending_exception (&error))
7645 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7647 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7648 gint32 const **exponents,
7649 gunichar2 const **digitLowerTable,
7650 gunichar2 const **digitUpperTable,
7651 gint64 const **tenPowersList,
7652 gint32 const **decHexDigits)
7654 *mantissas = Formatter_MantissaBitsTable;
7655 *exponents = Formatter_TensExponentTable;
7656 *digitLowerTable = Formatter_DigitLowerTable;
7657 *digitUpperTable = Formatter_DigitUpperTable;
7658 *tenPowersList = Formatter_TenPowersList;
7659 *decHexDigits = Formatter_DecHexDigits;
7663 add_modifier_to_array (MonoDomain *domain, MonoImage *image, MonoCustomMod *modifier, MonoArrayHandle dest, int dest_idx, MonoError *error)
7665 HANDLE_FUNCTION_ENTER ();
7666 mono_error_init (error);
7667 MonoClass *klass = mono_class_get_checked (image, modifier->token, error);
7671 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
7675 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rt);
7677 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
7681 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7682 * and avoid useless allocations.
7684 static MonoArrayHandle
7685 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7688 MonoDomain *domain = mono_domain_get ();
7690 mono_error_init (error);
7691 for (i = 0; i < type->num_mods; ++i) {
7692 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7696 return MONO_HANDLE_NEW (MonoArray, NULL);
7698 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
7702 for (i = 0; i < type->num_mods; ++i) {
7703 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7704 if (!add_modifier_to_array (domain, image, &type->modifiers[i], res, count , error))
7711 return MONO_HANDLE_NEW (MonoArray, NULL);
7714 ICALL_EXPORT MonoArrayHandle
7715 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameterHandle param, MonoBoolean optional, MonoError *error)
7717 mono_error_init (error);
7718 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
7719 MONO_HANDLE_GET (rt, param, ClassImpl);
7720 MonoType *type = MONO_HANDLE_GETVAL (rt, type);
7721 MonoObjectHandle member = MONO_HANDLE_NEW (MonoObject, NULL);
7722 MONO_HANDLE_GET (member, param, MemberImpl);
7723 MonoClass *member_class = mono_handle_class (member);
7724 MonoMethod *method = NULL;
7727 MonoMethodSignature *sig;
7729 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7730 method = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod, member), method);
7731 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7732 MonoProperty *prop = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionProperty, member), property);
7733 if (!(method = prop->get))
7737 char *type_name = mono_type_get_full_name (member_class);
7738 mono_error_set_not_supported (error, "Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7740 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7743 image = method->klass->image;
7744 pos = MONO_HANDLE_GETVAL (param, PositionImpl);
7745 sig = mono_method_signature (method);
7749 type = sig->params [pos];
7751 return type_array_from_modifiers (image, type, optional, error);
7755 get_property_type (MonoProperty *prop)
7757 MonoMethodSignature *sig;
7759 sig = mono_method_signature (prop->get);
7761 } else if (prop->set) {
7762 sig = mono_method_signature (prop->set);
7763 return sig->params [sig->param_count - 1];
7768 ICALL_EXPORT MonoArrayHandle
7769 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, MonoError *error)
7771 mono_error_init (error);
7772 MonoProperty *prop = MONO_HANDLE_GETVAL (property, property);
7773 MonoClass *klass = MONO_HANDLE_GETVAL (property, klass);
7774 MonoType *type = get_property_type (prop);
7775 MonoImage *image = klass->image;
7778 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7779 return type_array_from_modifiers (image, type, optional, error);
7783 *Construct a MonoType suited to be used to decode a constant blob object.
7785 * @type is the target type which will be constructed
7786 * @blob_type is the blob type, for example, that comes from the constant table
7787 * @real_type is the expected constructed type.
7790 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7792 type->type = blob_type;
7793 type->data.klass = NULL;
7794 if (blob_type == MONO_TYPE_CLASS)
7795 type->data.klass = mono_defaults.object_class;
7796 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7797 /* For enums, we need to use the base type */
7798 type->type = MONO_TYPE_VALUETYPE;
7799 type->data.klass = mono_class_from_mono_type (real_type);
7801 type->data.klass = mono_class_from_mono_type (real_type);
7804 ICALL_EXPORT MonoObject*
7805 property_info_get_default_value (MonoReflectionProperty *property)
7809 MonoProperty *prop = property->property;
7810 MonoType *type = get_property_type (prop);
7811 MonoDomain *domain = mono_object_domain (property);
7812 MonoTypeEnum def_type;
7813 const char *def_value;
7816 mono_class_init (prop->parent);
7818 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7819 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7823 def_value = mono_class_get_property_default_value (prop, &def_type);
7825 mono_type_from_blob_type (&blob_type, def_type, type);
7826 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7828 mono_error_set_pending_exception (&error);
7832 ICALL_EXPORT MonoBoolean
7833 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7836 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7837 MonoCustomAttrInfo *cinfo;
7840 mono_class_init_checked (attr_class, &error);
7841 if (mono_error_set_pending_exception (&error))
7844 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7845 if (!is_ok (&error)) {
7846 mono_error_set_pending_exception (&error);
7851 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7853 mono_custom_attrs_free (cinfo);
7857 ICALL_EXPORT MonoArray*
7858 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7860 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7865 mono_class_init_checked (attr_class, &error);
7866 if (mono_error_set_pending_exception (&error))
7870 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7871 if (!mono_error_ok (&error)) {
7872 mono_error_set_pending_exception (&error);
7879 ICALL_EXPORT MonoArray*
7880 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7884 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7885 mono_error_set_pending_exception (&error);
7890 ICALL_EXPORT MonoStringHandle
7891 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7894 MonoStringHandle display_name;
7896 mono_error_init (error);
7897 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7898 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7900 return display_name;
7904 static inline gint32
7905 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7907 return WAIT_TIMEOUT;
7909 #endif /* !HOST_WIN32 */
7912 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7914 return mono_icall_wait_for_input_idle (handle, milliseconds);
7918 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7920 return mono_process_current_pid ();
7923 ICALL_EXPORT MonoBoolean
7924 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7936 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7938 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7942 ICALL_EXPORT MonoObject*
7943 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7945 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7950 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7952 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7956 ICALL_EXPORT MonoObject*
7957 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7959 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7963 ICALL_EXPORT MonoBoolean
7964 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7966 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7971 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7973 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7977 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7979 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7984 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7986 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7990 ICALL_EXPORT mono_unichar2*
7991 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7993 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
8000 #ifndef DISABLE_ICALL_TABLES
8002 #define ICALL_TYPE(id,name,first)
8003 #define ICALL(id,name,func) Icall_ ## id,
8004 #define HANDLES(inner) inner
8007 #include "metadata/icall-def.h"
8013 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8014 #define ICALL(id,name,func)
8016 #define HANDLES(inner) inner
8018 #include "metadata/icall-def.h"
8024 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8025 #define ICALL(id,name,func)
8027 #define HANDLES(inner) inner
8029 guint16 first_icall;
8032 static const IcallTypeDesc
8033 icall_type_descs [] = {
8034 #include "metadata/icall-def.h"
8038 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8041 #define HANDLES(inner) inner
8043 #define ICALL_TYPE(id,name,first)
8046 #ifdef HAVE_ARRAY_ELEM_INIT
8047 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8048 #define MSGSTRFIELD1(line) str##line
8050 static const struct msgstrtn_t {
8051 #define ICALL(id,name,func)
8053 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8054 #include "metadata/icall-def.h"
8056 } icall_type_names_str = {
8057 #define ICALL_TYPE(id,name,first) (name),
8058 #include "metadata/icall-def.h"
8061 static const guint16 icall_type_names_idx [] = {
8062 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8063 #include "metadata/icall-def.h"
8066 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8068 static const struct msgstr_t {
8070 #define ICALL_TYPE(id,name,first)
8071 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8072 #include "metadata/icall-def.h"
8074 } icall_names_str = {
8075 #define ICALL(id,name,func) (name),
8076 #include "metadata/icall-def.h"
8079 static const guint16 icall_names_idx [] = {
8080 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8081 #include "metadata/icall-def.h"
8084 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8090 #define ICALL_TYPE(id,name,first) name,
8091 #define ICALL(id,name,func)
8092 static const char* const
8093 icall_type_names [] = {
8094 #include "metadata/icall-def.h"
8098 #define icall_type_name_get(id) (icall_type_names [(id)])
8102 #define ICALL_TYPE(id,name,first)
8103 #define ICALL(id,name,func) name,
8104 static const char* const
8106 #include "metadata/icall-def.h"
8109 #define icall_name_get(id) icall_names [(id)]
8111 #endif /* !HAVE_ARRAY_ELEM_INIT */
8114 #define HANDLES(inner) inner
8117 #define ICALL_TYPE(id,name,first)
8118 #define ICALL(id,name,func) func,
8119 static const gconstpointer
8120 icall_functions [] = {
8121 #include "metadata/icall-def.h"
8125 #ifdef ENABLE_ICALL_SYMBOL_MAP
8127 #define HANDLES(inner) inner
8130 #define ICALL_TYPE(id,name,first)
8131 #define ICALL(id,name,func) #func,
8132 static const gconstpointer
8133 icall_symbols [] = {
8134 #include "metadata/icall-def.h"
8141 #define ICALL_TYPE(id,name,first)
8142 #define ICALL(id,name,func) 0,
8144 #define HANDLES(inner) 1,
8146 icall_uses_handles [] = {
8147 #include "metadata/icall-def.h"
8152 #endif /* DISABLE_ICALL_TABLES */
8154 static mono_mutex_t icall_mutex;
8155 static GHashTable *icall_hash = NULL;
8156 static GHashTable *jit_icall_hash_name = NULL;
8157 static GHashTable *jit_icall_hash_addr = NULL;
8160 mono_icall_init (void)
8162 #ifndef DISABLE_ICALL_TABLES
8165 /* check that tables are sorted: disable in release */
8168 const char *prev_class = NULL;
8169 const char *prev_method;
8171 for (i = 0; i < Icall_type_num; ++i) {
8172 const IcallTypeDesc *desc;
8175 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8176 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8177 prev_class = icall_type_name_get (i);
8178 desc = &icall_type_descs [i];
8179 num_icalls = icall_desc_num_icalls (desc);
8180 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8181 for (j = 0; j < num_icalls; ++j) {
8182 const char *methodn = icall_name_get (desc->first_icall + j);
8183 if (prev_method && strcmp (prev_method, methodn) >= 0)
8184 g_print ("method %s should come before method %s\n", methodn, prev_method);
8185 prev_method = methodn;
8191 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8192 mono_os_mutex_init (&icall_mutex);
8196 mono_icall_lock (void)
8198 mono_locks_os_acquire (&icall_mutex, IcallLock);
8202 mono_icall_unlock (void)
8204 mono_locks_os_release (&icall_mutex, IcallLock);
8208 mono_icall_cleanup (void)
8210 g_hash_table_destroy (icall_hash);
8211 g_hash_table_destroy (jit_icall_hash_name);
8212 g_hash_table_destroy (jit_icall_hash_addr);
8213 mono_os_mutex_destroy (&icall_mutex);
8217 * mono_add_internal_call:
8218 * @name: method specification to surface to the managed world
8219 * @method: pointer to a C method to invoke when the method is called
8221 * This method surfaces the C function pointed by @method as a method
8222 * that has been surfaced in managed code with the method specified in
8223 * @name as an internal call.
8225 * Internal calls are surfaced to all app domains loaded and they are
8226 * accessibly by a type with the specified name.
8228 * You must provide a fully qualified type name, that is namespaces
8229 * and type name, followed by a colon and the method name, with an
8230 * optional signature to bind.
8232 * For example, the following are all valid declarations:
8234 * "MyApp.Services.ScriptService:Accelerate"
8235 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8237 * You use method parameters in cases where there might be more than
8238 * one surface method to managed code. That way you can register different
8239 * internal calls for different method overloads.
8241 * The internal calls are invoked with no marshalling. This means that .NET
8242 * types like System.String are exposed as `MonoString *` parameters. This is
8243 * different than the way that strings are surfaced in P/Invoke.
8245 * For more information on how the parameters are marshalled, see the
8246 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8249 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8250 * reference for more information on the format of method descriptions.
8253 mono_add_internal_call (const char *name, gconstpointer method)
8257 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8259 mono_icall_unlock ();
8262 #ifndef DISABLE_ICALL_TABLES
8264 #ifdef HAVE_ARRAY_ELEM_INIT
8266 compare_method_imap (const void *key, const void *elem)
8268 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8269 return strcmp (key, method_name);
8273 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8275 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);
8278 return (nameslot - &icall_names_idx [0]);
8282 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8284 gsize slotnum = find_slot_icall (imap, name);
8287 return (gboolean)icall_uses_handles [slotnum];
8291 find_method_icall (const IcallTypeDesc *imap, const char *name)
8293 gsize slotnum = find_slot_icall (imap, name);
8296 return (gpointer)icall_functions [slotnum];
8300 compare_class_imap (const void *key, const void *elem)
8302 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8303 return strcmp (key, class_name);
8306 static const IcallTypeDesc*
8307 find_class_icalls (const char *name)
8309 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);
8312 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8315 #else /* HAVE_ARRAY_ELEM_INIT */
8318 compare_method_imap (const void *key, const void *elem)
8320 const char** method_name = (const char**)elem;
8321 return strcmp (key, *method_name);
8325 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8327 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8330 return nameslot - icall_names;
8334 find_method_icall (const IcallTypeDesc *imap, const char *name)
8336 gsize slotnum = find_slot_icall (imap, name);
8339 return (gpointer)icall_functions [slotnum];
8343 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8345 gsize slotnum = find_slot_icall (imap, name);
8348 return (gboolean)icall_uses_handles [slotnum];
8352 compare_class_imap (const void *key, const void *elem)
8354 const char** class_name = (const char**)elem;
8355 return strcmp (key, *class_name);
8358 static const IcallTypeDesc*
8359 find_class_icalls (const char *name)
8361 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8364 return &icall_type_descs [nameslot - icall_type_names];
8367 #endif /* HAVE_ARRAY_ELEM_INIT */
8369 #endif /* DISABLE_ICALL_TABLES */
8372 * we should probably export this as an helper (handle nested types).
8373 * Returns the number of chars written in buf.
8376 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8378 int nspacelen, cnamelen;
8379 nspacelen = strlen (klass->name_space);
8380 cnamelen = strlen (klass->name);
8381 if (nspacelen + cnamelen + 2 > bufsize)
8384 memcpy (buf, klass->name_space, nspacelen);
8385 buf [nspacelen ++] = '.';
8387 memcpy (buf + nspacelen, klass->name, cnamelen);
8388 buf [nspacelen + cnamelen] = 0;
8389 return nspacelen + cnamelen;
8392 #ifdef DISABLE_ICALL_TABLES
8394 no_icall_table (void)
8396 g_assert_not_reached ();
8401 * mono_lookup_internal_call_full:
8402 * @method: the method to look up
8403 * @uses_handles: out argument if method needs handles around managed objects.
8405 * Returns a pointer to the icall code for the given method. If
8406 * uses_handles is not NULL, it will be set to TRUE if the method
8407 * needs managed objects wrapped using the infrastructure in handle.h
8409 * If the method is not found, warns and returns NULL.
8412 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8417 int typelen = 0, mlen, siglen;
8419 #ifndef DISABLE_ICALL_TABLES
8420 const IcallTypeDesc *imap = NULL;
8423 g_assert (method != NULL);
8425 if (method->is_inflated)
8426 method = ((MonoMethodInflated *) method)->declaring;
8428 if (method->klass->nested_in) {
8429 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8433 mname [pos++] = '/';
8436 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8442 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8447 #ifndef DISABLE_ICALL_TABLES
8448 imap = find_class_icalls (mname);
8451 mname [typelen] = ':';
8452 mname [typelen + 1] = ':';
8454 mlen = strlen (method->name);
8455 memcpy (mname + typelen + 2, method->name, mlen);
8456 sigstart = mname + typelen + 2 + mlen;
8459 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8460 siglen = strlen (tmpsig);
8461 if (typelen + mlen + siglen + 6 > sizeof (mname))
8464 memcpy (sigstart + 1, tmpsig, siglen);
8465 sigstart [siglen + 1] = ')';
8466 sigstart [siglen + 2] = 0;
8471 res = g_hash_table_lookup (icall_hash, mname);
8474 *uses_handles = FALSE;
8475 mono_icall_unlock ();;
8478 /* try without signature */
8480 res = g_hash_table_lookup (icall_hash, mname);
8483 *uses_handles = FALSE;
8484 mono_icall_unlock ();
8488 #ifdef DISABLE_ICALL_TABLES
8489 mono_icall_unlock ();
8490 /* Fail only when the result is actually used */
8491 /* mono_marshal_get_native_wrapper () depends on this */
8492 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8493 return ves_icall_System_String_ctor_RedirectToCreateString;
8495 return no_icall_table;
8497 /* it wasn't found in the static call tables */
8500 *uses_handles = FALSE;
8501 mono_icall_unlock ();
8504 res = find_method_icall (imap, sigstart - mlen);
8507 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8508 mono_icall_unlock ();
8511 /* try _with_ signature */
8513 res = find_method_icall (imap, sigstart - mlen);
8516 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8517 mono_icall_unlock ();
8521 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8522 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8523 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8524 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8525 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");
8526 g_print ("If you see other errors or faults after this message they are probably related\n");
8527 g_print ("and you need to fix your mono install first.\n");
8529 mono_icall_unlock ();
8536 mono_lookup_internal_call (MonoMethod *method)
8538 return mono_lookup_internal_call_full (method, NULL);
8541 #ifdef ENABLE_ICALL_SYMBOL_MAP
8543 func_cmp (gconstpointer key, gconstpointer p)
8545 return (gsize)key - (gsize)*(gsize*)p;
8550 * mono_lookup_icall_symbol:
8552 * Given the icall METHOD, returns its C symbol.
8555 mono_lookup_icall_symbol (MonoMethod *m)
8557 #ifdef DISABLE_ICALL_TABLES
8558 g_assert_not_reached ();
8561 #ifdef ENABLE_ICALL_SYMBOL_MAP
8565 static gconstpointer *functions_sorted;
8566 static const char**symbols_sorted;
8567 static gboolean inited;
8572 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8573 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8574 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8575 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8576 /* Bubble sort the two arrays */
8580 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8581 if (functions_sorted [i] > functions_sorted [i + 1]) {
8584 tmp = functions_sorted [i];
8585 functions_sorted [i] = functions_sorted [i + 1];
8586 functions_sorted [i + 1] = tmp;
8587 tmp = symbols_sorted [i];
8588 symbols_sorted [i] = symbols_sorted [i + 1];
8589 symbols_sorted [i + 1] = tmp;
8596 func = mono_lookup_internal_call (m);
8599 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8603 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8605 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8606 g_assert_not_reached ();
8613 type_from_typename (char *type_name)
8615 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8617 if (!strcmp (type_name, "int"))
8618 klass = mono_defaults.int_class;
8619 else if (!strcmp (type_name, "ptr"))
8620 klass = mono_defaults.int_class;
8621 else if (!strcmp (type_name, "void"))
8622 klass = mono_defaults.void_class;
8623 else if (!strcmp (type_name, "int32"))
8624 klass = mono_defaults.int32_class;
8625 else if (!strcmp (type_name, "uint32"))
8626 klass = mono_defaults.uint32_class;
8627 else if (!strcmp (type_name, "int8"))
8628 klass = mono_defaults.sbyte_class;
8629 else if (!strcmp (type_name, "uint8"))
8630 klass = mono_defaults.byte_class;
8631 else if (!strcmp (type_name, "int16"))
8632 klass = mono_defaults.int16_class;
8633 else if (!strcmp (type_name, "uint16"))
8634 klass = mono_defaults.uint16_class;
8635 else if (!strcmp (type_name, "long"))
8636 klass = mono_defaults.int64_class;
8637 else if (!strcmp (type_name, "ulong"))
8638 klass = mono_defaults.uint64_class;
8639 else if (!strcmp (type_name, "float"))
8640 klass = mono_defaults.single_class;
8641 else if (!strcmp (type_name, "double"))
8642 klass = mono_defaults.double_class;
8643 else if (!strcmp (type_name, "object"))
8644 klass = mono_defaults.object_class;
8645 else if (!strcmp (type_name, "obj"))
8646 klass = mono_defaults.object_class;
8647 else if (!strcmp (type_name, "string"))
8648 klass = mono_defaults.string_class;
8649 else if (!strcmp (type_name, "bool"))
8650 klass = mono_defaults.boolean_class;
8651 else if (!strcmp (type_name, "boolean"))
8652 klass = mono_defaults.boolean_class;
8654 g_error ("%s", type_name);
8655 g_assert_not_reached ();
8657 return &klass->byval_arg;
8661 * LOCKING: Take the corlib image lock.
8663 MonoMethodSignature*
8664 mono_create_icall_signature (const char *sigstr)
8669 MonoMethodSignature *res, *res2;
8670 MonoImage *corlib = mono_defaults.corlib;
8672 mono_image_lock (corlib);
8673 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8674 mono_image_unlock (corlib);
8679 parts = g_strsplit (sigstr, " ", 256);
8688 res = mono_metadata_signature_alloc (corlib, len - 1);
8693 * Under windows, the default pinvoke calling convention is STDCALL but
8696 res->call_convention = MONO_CALL_C;
8699 res->ret = type_from_typename (parts [0]);
8700 for (i = 1; i < len; ++i) {
8701 res->params [i - 1] = type_from_typename (parts [i]);
8706 mono_image_lock (corlib);
8707 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8709 res = res2; /*Value is allocated in the image pool*/
8711 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8712 mono_image_unlock (corlib);
8718 mono_find_jit_icall_by_name (const char *name)
8720 MonoJitICallInfo *info;
8721 g_assert (jit_icall_hash_name);
8724 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8725 mono_icall_unlock ();
8730 mono_find_jit_icall_by_addr (gconstpointer addr)
8732 MonoJitICallInfo *info;
8733 g_assert (jit_icall_hash_addr);
8736 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8737 mono_icall_unlock ();
8743 * mono_get_jit_icall_info:
8745 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8746 * caller should access it while holding the icall lock.
8749 mono_get_jit_icall_info (void)
8751 return jit_icall_hash_name;
8755 * mono_lookup_jit_icall_symbol:
8757 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8760 mono_lookup_jit_icall_symbol (const char *name)
8762 MonoJitICallInfo *info;
8763 const char *res = NULL;
8766 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8768 res = info->c_symbol;
8769 mono_icall_unlock ();
8774 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8777 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8778 mono_icall_unlock ();
8782 * 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
8783 * icalls without wrappers in some cases.
8786 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8788 MonoJitICallInfo *info;
8795 if (!jit_icall_hash_name) {
8796 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8797 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8800 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8801 g_warning ("jit icall already defined \"%s\"\n", name);
8802 g_assert_not_reached ();
8805 info = g_new0 (MonoJitICallInfo, 1);
8810 info->c_symbol = c_symbol;
8811 info->no_raise = no_raise;
8814 info->wrapper = func;
8816 info->wrapper = NULL;
8819 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8820 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8822 mono_icall_unlock ();
8827 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8829 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);