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;
1409 char *str = mono_string_handle_to_utf8 (name, error);
1413 parsedOk = mono_reflection_parse_type (str, &info);
1415 /* mono_reflection_parse_type() mangles the string */
1417 mono_reflection_free_type_info (&info);
1419 mono_error_set_argument (error, "typeName", "failed parse: %s", str);
1423 MonoReflectionTypeHandle type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, error);
1425 if (!is_ok (error)) {
1426 mono_reflection_free_type_info (&info);
1430 if (MONO_HANDLE_IS_NULL (type)) {
1432 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1434 if (info.assembly.name)
1435 aname = mono_stringify_assembly_name (&info.assembly);
1436 else if (caller_assembly)
1437 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1439 aname = g_strdup ("");
1440 mono_error_set_type_load_name (error, tname, aname, "");
1442 mono_reflection_free_type_info (&info);
1448 if (!is_ok (error)) {
1450 mono_error_cleanup (error);
1451 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
1458 ICALL_EXPORT MonoReflectionTypeHandle
1459 ves_icall_System_Type_internal_from_handle (MonoType *handle, MonoError *error)
1461 mono_error_init (error);
1462 MonoDomain *domain = mono_domain_get ();
1464 return mono_type_get_object_handle (domain, handle, error);
1467 ICALL_EXPORT MonoType*
1468 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1470 return mono_class_get_type (klass);
1474 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1476 g_ptr_array_free (ptr_array, TRUE);
1480 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1486 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1489 char *res = mono_string_to_utf8_checked (s, &error);
1490 mono_error_set_pending_exception (&error);
1494 /* System.TypeCode */
1513 TYPECODE_STRING = 18
1516 ICALL_EXPORT guint32
1517 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1519 int t = type->type->type;
1521 if (type->type->byref)
1522 return TYPECODE_OBJECT;
1526 case MONO_TYPE_VOID:
1527 return TYPECODE_OBJECT;
1528 case MONO_TYPE_BOOLEAN:
1529 return TYPECODE_BOOLEAN;
1531 return TYPECODE_BYTE;
1533 return TYPECODE_SBYTE;
1535 return TYPECODE_UINT16;
1537 return TYPECODE_INT16;
1538 case MONO_TYPE_CHAR:
1539 return TYPECODE_CHAR;
1543 return TYPECODE_OBJECT;
1545 return TYPECODE_UINT32;
1547 return TYPECODE_INT32;
1549 return TYPECODE_UINT64;
1551 return TYPECODE_INT64;
1553 return TYPECODE_SINGLE;
1555 return TYPECODE_DOUBLE;
1556 case MONO_TYPE_VALUETYPE: {
1557 MonoClass *klass = type->type->data.klass;
1559 if (klass->enumtype) {
1560 t = mono_class_enum_basetype (klass)->type;
1562 } else if (mono_is_corlib_image (klass->image)) {
1563 if (strcmp (klass->name_space, "System") == 0) {
1564 if (strcmp (klass->name, "Decimal") == 0)
1565 return TYPECODE_DECIMAL;
1566 else if (strcmp (klass->name, "DateTime") == 0)
1567 return TYPECODE_DATETIME;
1570 return TYPECODE_OBJECT;
1572 case MONO_TYPE_STRING:
1573 return TYPECODE_STRING;
1574 case MONO_TYPE_SZARRAY:
1575 case MONO_TYPE_ARRAY:
1576 case MONO_TYPE_OBJECT:
1578 case MONO_TYPE_MVAR:
1579 case MONO_TYPE_TYPEDBYREF:
1580 return TYPECODE_OBJECT;
1581 case MONO_TYPE_CLASS:
1583 MonoClass *klass = type->type->data.klass;
1584 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1585 if (strcmp (klass->name, "DBNull") == 0)
1586 return TYPECODE_DBNULL;
1589 return TYPECODE_OBJECT;
1590 case MONO_TYPE_GENERICINST:
1591 return TYPECODE_OBJECT;
1593 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1599 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1601 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1602 return mono_class_enum_basetype (type->data.klass);
1603 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1604 return mono_class_enum_basetype (type->data.generic_class->container_class);
1608 ICALL_EXPORT guint32
1609 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_c, MonoError *error)
1611 mono_error_init (error);
1613 g_assert (!MONO_HANDLE_IS_NULL (ref_type));
1615 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1616 MonoClass *klass = mono_class_from_mono_type (type);
1617 MonoType *ctype = MONO_HANDLE_GETVAL (ref_c, type);
1618 MonoClass *klassc = mono_class_from_mono_type (ctype);
1620 if (type->byref ^ ctype->byref)
1624 MonoType *t = mono_type_get_underlying_type_ignore_byref (type);
1625 MonoType *ot = mono_type_get_underlying_type_ignore_byref (ctype);
1627 klass = mono_class_from_mono_type (t);
1628 klassc = mono_class_from_mono_type (ot);
1630 if (mono_type_is_primitive (t)) {
1631 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1632 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1633 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1634 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1635 return t->type == ot->type;
1637 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1640 if (klass->valuetype)
1641 return klass == klassc;
1642 return klass->valuetype == klassc->valuetype;
1645 return mono_class_is_assignable_from (klass, klassc);
1648 ICALL_EXPORT guint32
1649 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1652 MonoClass *klass = mono_class_from_mono_type (type->type);
1653 mono_class_init_checked (klass, &error);
1654 if (!is_ok (&error)) {
1655 mono_error_set_pending_exception (&error);
1658 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1659 mono_error_set_pending_exception (&error);
1663 ICALL_EXPORT guint32
1664 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionTypeHandle ref_type, MonoError *error)
1666 mono_error_init (error);
1667 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1668 MonoClass *klass = mono_class_from_mono_type (type);
1669 return mono_class_get_flags (klass);
1672 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1673 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h, MonoError *error)
1675 mono_error_init (error);
1676 MonoDomain *domain = MONO_HANDLE_DOMAIN (field_h);
1677 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1678 MonoClass *klass = field->parent;
1680 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1681 if (mono_class_is_gtd (klass) ||
1682 (gklass && gklass->context.class_inst->is_open))
1683 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1685 MonoType *ftype = mono_field_get_type (field);
1686 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1687 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1689 MonoMarshalType *info = mono_marshal_load_type_info (klass);
1691 for (int i = 0; i < info->num_fields; ++i) {
1692 if (info->fields [i].field == field) {
1693 if (!info->fields [i].mspec)
1694 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1696 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain, klass, info->fields [i].mspec, error);
1701 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1704 ICALL_EXPORT MonoReflectionFieldHandle
1705 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type, MonoError *error)
1711 mono_error_init (error);
1714 klass = handle->parent;
1716 klass = mono_class_from_mono_type (type);
1718 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1721 /* The managed code will throw the exception */
1722 return MONO_HANDLE_CAST (MonoReflectionField, NULL_HANDLE);
1725 return mono_field_get_object_handle (mono_domain_get (), klass, handle, error);
1728 ICALL_EXPORT MonoReflectionEventHandle
1729 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type, MonoError *error)
1735 mono_error_init (error);
1738 klass = handle->parent;
1740 klass = mono_class_from_mono_type (type);
1742 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1744 /* Managed code will throw an exception */
1745 return MONO_HANDLE_CAST (MonoReflectionEvent, NULL_HANDLE);
1748 return mono_event_get_object_handle (mono_domain_get (), klass, handle, error);
1752 ICALL_EXPORT MonoReflectionPropertyHandle
1753 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type, MonoError *error)
1755 mono_error_init (error);
1761 klass = handle->parent;
1763 klass = mono_class_from_mono_type (type);
1765 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1767 /* Managed code will throw an exception */
1768 return MONO_HANDLE_CAST (MonoReflectionProperty, NULL_HANDLE);
1771 return mono_property_get_object_handle (mono_domain_get (), klass, handle, error);
1774 ICALL_EXPORT MonoArrayHandle
1775 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
1777 mono_error_init (error);
1778 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1780 MonoType *type = mono_field_get_type_checked (field, error);
1782 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1784 return type_array_from_modifiers (field->parent->image, type, optional, error);
1788 vell_icall_get_method_attributes (MonoMethod *method)
1790 return method->flags;
1794 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1797 MonoReflectionType *rt;
1798 MonoDomain *domain = mono_domain_get ();
1799 MonoMethodSignature* sig;
1801 sig = mono_method_signature_checked (method, &error);
1802 if (!mono_error_ok (&error)) {
1803 mono_error_set_pending_exception (&error);
1807 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1808 if (!mono_error_ok (&error)) {
1809 mono_error_set_pending_exception (&error);
1813 MONO_STRUCT_SETREF (info, parent, rt);
1815 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1816 if (!mono_error_ok (&error)) {
1817 mono_error_set_pending_exception (&error);
1821 MONO_STRUCT_SETREF (info, ret, rt);
1823 info->attrs = method->flags;
1824 info->implattrs = method->iflags;
1825 if (sig->call_convention == MONO_CALL_DEFAULT)
1826 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1828 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1833 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1836 ICALL_EXPORT MonoArrayHandle
1837 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod *method, MonoReflectionMethodHandle member, MonoError *error)
1839 mono_error_init (error);
1840 MonoDomain *domain = mono_domain_get ();
1842 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1843 MONO_HANDLE_GET (reftype, member, reftype);
1844 MonoClass *klass = NULL;
1845 if (!MONO_HANDLE_IS_NULL (reftype))
1846 klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype, type));
1847 return mono_param_get_objects_internal (domain, method, klass, error);
1850 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1851 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method, MonoError *error)
1853 mono_error_init (error);
1854 MonoDomain *domain = mono_domain_get ();
1855 MonoReflectionMarshalAsAttributeHandle res = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
1857 MonoMarshalSpec **mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1858 mono_method_get_marshal_info (method, mspecs);
1861 MONO_HANDLE_ASSIGN (res, mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], error));
1867 for (int i = mono_method_signature (method)->param_count; i >= 0; i--)
1869 mono_metadata_free_marshal_spec (mspecs [i]);
1876 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1878 MonoClass *parent = field->field->parent;
1879 mono_class_setup_fields (parent);
1881 return field->field->offset - sizeof (MonoObject);
1884 ICALL_EXPORT MonoReflectionTypeHandle
1885 ves_icall_MonoField_GetParentType (MonoReflectionFieldHandle field, MonoBoolean declaring, MonoError *error)
1887 mono_error_init (error);
1888 MonoDomain *domain = MONO_HANDLE_DOMAIN (field);
1892 MonoClassField *f = MONO_HANDLE_GETVAL (field, field);
1895 parent = MONO_HANDLE_GETVAL (field, klass);
1898 return mono_type_get_object_handle (domain, &parent->byval_arg, error);
1901 ICALL_EXPORT MonoObject *
1902 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1905 MonoClass *fklass = field->klass;
1906 MonoClassField *cf = field->field;
1907 MonoDomain *domain = mono_object_domain (field);
1909 if (fklass->image->assembly->ref_only) {
1910 mono_set_pending_exception (mono_get_exception_invalid_operation (
1911 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1915 if (mono_security_core_clr_enabled () &&
1916 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1917 mono_error_set_pending_exception (&error);
1921 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1922 mono_error_set_pending_exception (&error);
1927 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1930 MonoClassField *cf = field->field;
1934 if (field->klass->image->assembly->ref_only) {
1935 mono_set_pending_exception (mono_get_exception_invalid_operation (
1936 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1940 if (mono_security_core_clr_enabled () &&
1941 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1942 mono_error_set_pending_exception (&error);
1946 type = mono_field_get_type_checked (cf, &error);
1947 if (!mono_error_ok (&error)) {
1948 mono_error_set_pending_exception (&error);
1952 v = (gchar *) value;
1954 switch (type->type) {
1957 case MONO_TYPE_BOOLEAN:
1960 case MONO_TYPE_CHAR:
1969 case MONO_TYPE_VALUETYPE:
1972 v += sizeof (MonoObject);
1974 case MONO_TYPE_STRING:
1975 case MONO_TYPE_OBJECT:
1976 case MONO_TYPE_CLASS:
1977 case MONO_TYPE_ARRAY:
1978 case MONO_TYPE_SZARRAY:
1981 case MONO_TYPE_GENERICINST: {
1982 MonoGenericClass *gclass = type->data.generic_class;
1983 g_assert (!gclass->context.class_inst->is_open);
1985 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1986 MonoClass *nklass = mono_class_from_mono_type (type);
1987 MonoObject *nullable;
1990 * Convert the boxed vtype into a Nullable structure.
1991 * This is complicated by the fact that Nullables have
1992 * a variable structure.
1994 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
1995 if (!mono_error_ok (&error)) {
1996 mono_error_set_pending_exception (&error);
2000 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2002 v = (gchar *)mono_object_unbox (nullable);
2005 if (gclass->container_class->valuetype && (v != NULL))
2006 v += sizeof (MonoObject);
2010 g_error ("type 0x%x not handled in "
2011 "ves_icall_FieldInfo_SetValueInternal", type->type);
2016 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2017 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2018 if (!is_ok (&error)) {
2019 mono_error_set_pending_exception (&error);
2022 if (!vtable->initialized) {
2023 if (!mono_runtime_class_init_full (vtable, &error)) {
2024 mono_error_set_pending_exception (&error);
2028 mono_field_static_set_value (vtable, cf, v);
2030 mono_field_set_value (obj, cf, v);
2035 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2044 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2045 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2049 if (MONO_TYPE_IS_REFERENCE (f->type))
2050 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2052 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2055 ICALL_EXPORT MonoObject *
2056 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2058 MonoObject *o = NULL;
2059 MonoClassField *field = rfield->field;
2061 MonoDomain *domain = mono_object_domain (rfield);
2063 MonoTypeEnum def_type;
2064 const char *def_value;
2068 mono_class_init (field->parent);
2070 t = mono_field_get_type_checked (field, &error);
2071 if (!mono_error_ok (&error)) {
2072 mono_error_set_pending_exception (&error);
2076 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2077 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2081 if (image_is_dynamic (field->parent->image)) {
2082 MonoClass *klass = field->parent;
2083 int fidx = field - klass->fields;
2084 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2086 g_assert (def_values);
2087 def_type = def_values [fidx].def_type;
2088 def_value = def_values [fidx].data;
2090 if (def_type == MONO_TYPE_END) {
2091 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2095 def_value = mono_class_get_field_default_value (field, &def_type);
2096 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2098 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2103 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2107 case MONO_TYPE_BOOLEAN:
2110 case MONO_TYPE_CHAR:
2118 case MONO_TYPE_R8: {
2121 /* boxed value type */
2122 t = g_new0 (MonoType, 1);
2124 klass = mono_class_from_mono_type (t);
2126 o = mono_object_new_checked (domain, klass, &error);
2127 if (!mono_error_ok (&error)) {
2128 mono_error_set_pending_exception (&error);
2131 v = ((gchar *) o) + sizeof (MonoObject);
2132 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2133 if (mono_error_set_pending_exception (&error))
2137 case MONO_TYPE_STRING:
2138 case MONO_TYPE_CLASS:
2139 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2140 if (mono_error_set_pending_exception (&error))
2144 g_assert_not_reached ();
2150 ICALL_EXPORT MonoReflectionTypeHandle
2151 ves_icall_MonoField_ResolveType (MonoReflectionFieldHandle ref_field, MonoError *error)
2153 mono_error_init (error);
2154 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_field);
2155 MonoClassField *field = MONO_HANDLE_GETVAL (ref_field, field);
2156 MonoType *type = mono_field_get_type_checked (field, error);
2157 if (!is_ok (error)) {
2158 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2160 return mono_type_get_object_handle (domain, type, error);
2163 /* From MonoProperty.cs */
2165 PInfo_Attributes = 1,
2166 PInfo_GetMethod = 1 << 1,
2167 PInfo_SetMethod = 1 << 2,
2168 PInfo_ReflectedType = 1 << 3,
2169 PInfo_DeclaringType = 1 << 4,
2174 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2177 MonoReflectionType *rt;
2178 MonoReflectionMethod *rm;
2179 MonoDomain *domain = mono_object_domain (property);
2180 const MonoProperty *pproperty = property->property;
2182 if ((req_info & PInfo_ReflectedType) != 0) {
2183 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2184 if (mono_error_set_pending_exception (&error))
2187 MONO_STRUCT_SETREF (info, parent, rt);
2189 if ((req_info & PInfo_DeclaringType) != 0) {
2190 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2191 if (mono_error_set_pending_exception (&error))
2194 MONO_STRUCT_SETREF (info, declaring_type, rt);
2197 if ((req_info & PInfo_Name) != 0)
2198 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2200 if ((req_info & PInfo_Attributes) != 0)
2201 info->attrs = pproperty->attrs;
2203 if ((req_info & PInfo_GetMethod) != 0) {
2204 if (pproperty->get &&
2205 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2206 pproperty->get->klass == property->klass)) {
2207 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2208 if (mono_error_set_pending_exception (&error))
2214 MONO_STRUCT_SETREF (info, get, rm);
2216 if ((req_info & PInfo_SetMethod) != 0) {
2217 if (pproperty->set &&
2218 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2219 pproperty->set->klass == property->klass)) {
2220 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2221 if (mono_error_set_pending_exception (&error))
2227 MONO_STRUCT_SETREF (info, set, rm);
2230 * There may be other methods defined for properties, though, it seems they are not exposed
2231 * in the reflection API
2236 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2239 MonoReflectionType *rt;
2240 MonoReflectionMethod *rm;
2241 MonoDomain *domain = mono_object_domain (event);
2243 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2244 if (mono_error_set_pending_exception (&error))
2247 MONO_STRUCT_SETREF (info, reflected_type, rt);
2249 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2250 if (mono_error_set_pending_exception (&error))
2253 MONO_STRUCT_SETREF (info, declaring_type, rt);
2255 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2256 info->attrs = event->event->attrs;
2258 if (event->event->add) {
2259 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2260 if (mono_error_set_pending_exception (&error))
2266 MONO_STRUCT_SETREF (info, add_method, rm);
2268 if (event->event->remove) {
2269 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2270 if (mono_error_set_pending_exception (&error))
2276 MONO_STRUCT_SETREF (info, remove_method, rm);
2278 if (event->event->raise) {
2279 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2280 if (mono_error_set_pending_exception (&error))
2286 MONO_STRUCT_SETREF (info, raise_method, rm);
2288 #ifndef MONO_SMALL_CONFIG
2289 if (event->event->other) {
2291 while (event->event->other [n])
2293 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2294 if (mono_error_set_pending_exception (&error))
2296 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2298 for (i = 0; i < n; i++) {
2299 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2300 if (mono_error_set_pending_exception (&error))
2302 mono_array_setref (info->other_methods, i, rm);
2309 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2314 mono_class_setup_interfaces (klass, error);
2315 if (!mono_error_ok (error))
2318 for (i = 0; i < klass->interface_count; i++) {
2319 ic = klass->interfaces [i];
2320 g_hash_table_insert (ifaces, ic, ic);
2322 collect_interfaces (ic, ifaces, error);
2323 if (!mono_error_ok (error))
2329 MonoArray *iface_array;
2330 MonoGenericContext *context;
2334 } FillIfaceArrayData;
2337 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2339 MonoReflectionType *rt;
2340 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2341 MonoClass *ic = (MonoClass *)key;
2342 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2344 if (!mono_error_ok (data->error))
2347 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2348 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2349 if (!mono_error_ok (data->error))
2353 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2354 if (!mono_error_ok (data->error))
2357 mono_array_setref (data->iface_array, data->next_idx++, rt);
2360 mono_metadata_free_type (inflated);
2364 get_interfaces_hash (gconstpointer v1)
2366 MonoClass *k = (MonoClass*)v1;
2368 return k->type_token;
2371 ICALL_EXPORT MonoArray*
2372 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2375 MonoClass *klass = mono_class_from_mono_type (type->type);
2377 FillIfaceArrayData data = { 0 };
2380 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2382 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2383 data.context = mono_class_get_context (klass);
2384 klass = mono_class_get_generic_class (klass)->container_class;
2387 for (parent = klass; parent; parent = parent->parent) {
2388 mono_class_setup_interfaces (parent, &error);
2389 if (!mono_error_ok (&error))
2391 collect_interfaces (parent, iface_hash, &error);
2392 if (!mono_error_ok (&error))
2396 data.error = &error;
2397 data.domain = mono_object_domain (type);
2399 len = g_hash_table_size (iface_hash);
2401 g_hash_table_destroy (iface_hash);
2402 if (!data.domain->empty_types) {
2403 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2404 if (!is_ok (&error))
2407 return data.domain->empty_types;
2410 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2411 if (!is_ok (&error))
2413 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2414 if (!mono_error_ok (&error))
2417 g_hash_table_destroy (iface_hash);
2418 return data.iface_array;
2421 g_hash_table_destroy (iface_hash);
2422 mono_error_set_pending_exception (&error);
2427 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2429 gboolean variance_used;
2430 MonoClass *klass = mono_class_from_mono_type (type->type);
2431 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2432 MonoReflectionMethod *member;
2435 int i = 0, len, ioffset;
2439 mono_class_init_checked (klass, &error);
2440 if (mono_error_set_pending_exception (&error))
2442 mono_class_init_checked (iclass, &error);
2443 if (mono_error_set_pending_exception (&error))
2446 mono_class_setup_vtable (klass);
2448 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2452 len = mono_class_num_methods (iclass);
2453 domain = mono_object_domain (type);
2454 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2455 if (mono_error_set_pending_exception (&error))
2457 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2458 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2459 if (mono_error_set_pending_exception (&error))
2461 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2463 while ((method = mono_class_get_methods (iclass, &iter))) {
2464 member = mono_method_get_object_checked (domain, method, iclass, &error);
2465 if (mono_error_set_pending_exception (&error))
2467 mono_array_setref (*methods, i, member);
2468 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2469 if (mono_error_set_pending_exception (&error))
2471 mono_array_setref (*targets, i, member);
2478 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2481 MonoClass *klass = mono_class_from_mono_type (type->type);
2483 mono_class_init_checked (klass, &error);
2484 if (mono_error_set_pending_exception (&error))
2487 if (image_is_dynamic (klass->image)) {
2488 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2489 *packing = tb->packing_size;
2490 *size = tb->class_size;
2492 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2496 ICALL_EXPORT MonoReflectionTypeHandle
2497 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionTypeHandle ref_type, MonoError *error)
2499 mono_error_init (error);
2501 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2502 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2504 if (!type->byref && type->type == MONO_TYPE_SZARRAY) {
2505 return mono_type_get_object_handle (domain, &type->data.klass->byval_arg, error);
2508 MonoClass *klass = mono_class_from_mono_type (type);
2509 mono_class_init_checked (klass, error);
2511 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2513 // GetElementType should only return a type for:
2514 // Array Pointer PassedByRef
2516 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2517 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2518 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2519 else if (klass->element_class && type->type == MONO_TYPE_PTR)
2520 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2522 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2525 ICALL_EXPORT MonoReflectionTypeHandle
2526 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionTypeHandle ref_type, MonoError *error)
2528 mono_error_init (error);
2530 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2531 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2534 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2536 MonoClass *klass = mono_class_from_mono_type (type);
2538 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2540 return mono_type_get_object_handle (domain, &klass->parent->byval_arg, error);
2543 ICALL_EXPORT MonoBoolean
2544 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionTypeHandle ref_type, MonoError *error)
2546 mono_error_init (error);
2547 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2548 return type->type == MONO_TYPE_PTR;
2551 ICALL_EXPORT MonoBoolean
2552 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type, MonoError *error)
2554 mono_error_init (error);
2555 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2556 return (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)));
2559 ICALL_EXPORT MonoBoolean
2560 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type, MonoError *error)
2562 mono_error_init (error);
2563 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2567 ICALL_EXPORT MonoBoolean
2568 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionTypeHandle ref_type, MonoError *error)
2570 mono_error_init (error);
2571 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2572 MonoClass *klass = mono_class_from_mono_type (type);
2573 mono_class_init_checked (klass, error);
2577 return mono_class_is_com_object (klass);
2580 ICALL_EXPORT guint32
2581 ves_icall_reflection_get_token (MonoObjectHandle obj, MonoError *error)
2583 mono_error_init (error);
2584 return mono_reflection_get_token_checked (obj, error);
2587 ICALL_EXPORT MonoReflectionModuleHandle
2588 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2590 mono_error_init (error);
2591 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2592 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2593 MonoClass *klass = mono_class_from_mono_type (t);
2594 return mono_module_get_object_handle (domain, klass->image, error);
2597 ICALL_EXPORT MonoReflectionAssemblyHandle
2598 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2600 mono_error_init (error);
2601 MonoDomain *domain = mono_domain_get ();
2602 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2603 MonoClass *klass = mono_class_from_mono_type (t);
2604 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2607 ICALL_EXPORT MonoReflectionType*
2608 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2611 MonoReflectionType *ret;
2612 MonoDomain *domain = mono_domain_get ();
2615 if (type->type->byref)
2617 if (type->type->type == MONO_TYPE_VAR) {
2618 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2619 klass = param ? param->owner.klass : NULL;
2620 } else if (type->type->type == MONO_TYPE_MVAR) {
2621 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2622 klass = param ? param->owner.method->klass : NULL;
2624 klass = mono_class_from_mono_type (type->type)->nested_in;
2630 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2631 mono_error_set_pending_exception (&error);
2636 ICALL_EXPORT MonoStringHandle
2637 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2639 MonoDomain *domain = mono_domain_get ();
2640 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2641 MonoClass *klass = mono_class_from_mono_type (type);
2644 char *n = g_strdup_printf ("%s&", klass->name);
2645 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2651 return mono_string_new_handle (domain, klass->name, error);
2655 ICALL_EXPORT MonoStringHandle
2656 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2658 MonoDomain *domain = mono_domain_get ();
2659 MonoClass *klass = mono_class_from_mono_type_handle (type);
2661 while (klass->nested_in)
2662 klass = klass->nested_in;
2664 if (klass->name_space [0] == '\0')
2665 return NULL_HANDLE_STRING;
2667 return mono_string_new_handle (domain, klass->name_space, error);
2671 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionTypeHandle ref_type, MonoError *error)
2673 mono_error_init (error);
2674 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2676 if (type->type != MONO_TYPE_ARRAY && type->type != MONO_TYPE_SZARRAY) {
2677 mono_error_set_argument (error, "type", "Type must be an array type");
2681 MonoClass *klass = mono_class_from_mono_type (type);
2687 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2689 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2692 ICALL_EXPORT MonoArray*
2693 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2696 MonoReflectionType *rt;
2698 MonoClass *klass, *pklass;
2699 MonoDomain *domain = mono_object_domain (type);
2702 klass = mono_class_from_mono_type (type->type);
2704 if (mono_class_is_gtd (klass)) {
2705 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2706 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2707 if (mono_error_set_pending_exception (&error))
2709 for (i = 0; i < container->type_argc; ++i) {
2710 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2712 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2713 if (mono_error_set_pending_exception (&error))
2716 mono_array_setref (res, i, rt);
2718 } else if (mono_class_is_ginst (klass)) {
2719 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2720 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2721 if (mono_error_set_pending_exception (&error))
2723 for (i = 0; i < inst->type_argc; ++i) {
2724 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2725 if (mono_error_set_pending_exception (&error))
2728 mono_array_setref (res, i, rt);
2736 ICALL_EXPORT gboolean
2737 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionTypeHandle ref_type, MonoError *error)
2739 mono_error_init (error);
2741 if (!IS_MONOTYPE (MONO_HANDLE_RAW(ref_type)))
2744 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2748 MonoClass *klass = mono_class_from_mono_type (type);
2749 return mono_class_is_gtd (klass);
2752 ICALL_EXPORT MonoReflectionTypeHandle
2753 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionTypeHandle ref_type, MonoError *error)
2755 mono_error_init (error);
2756 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2758 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW (MonoReflectionType, NULL);
2763 MonoClass *klass = mono_class_from_mono_type (type);
2765 if (mono_class_is_gtd (klass)) {
2766 /* check this one */
2767 MONO_HANDLE_ASSIGN (ret, ref_type);
2770 if (mono_class_is_ginst (klass)) {
2771 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2773 guint32 ref_info_handle = mono_class_get_ref_info_handle (klass);
2775 if (generic_class->wastypebuilder && ref_info_handle) {
2776 MonoObjectHandle tb = mono_gchandle_get_target_handle (ref_info_handle);
2777 g_assert (!MONO_HANDLE_IS_NULL (tb));
2778 MONO_HANDLE_ASSIGN (ret, tb);
2780 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2781 MONO_HANDLE_ASSIGN (ret, mono_type_get_object_handle (domain, &generic_class->byval_arg, error));
2788 ICALL_EXPORT MonoReflectionType*
2789 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2792 MonoReflectionType *ret;
2794 MonoType *geninst, **types;
2797 g_assert (IS_MONOTYPE (type));
2798 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2799 if (mono_error_set_pending_exception (&error))
2802 count = mono_array_length (type_array);
2803 types = g_new0 (MonoType *, count);
2805 for (i = 0; i < count; i++) {
2806 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2807 types [i] = t->type;
2810 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2813 mono_error_set_pending_exception (&error);
2817 klass = mono_class_from_mono_type (geninst);
2819 /*we might inflate to the GTD*/
2820 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2821 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2825 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2826 mono_error_set_pending_exception (&error);
2831 ICALL_EXPORT gboolean
2832 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionTypeHandle ref_type, MonoError *error)
2834 mono_error_init (error);
2837 if (!IS_MONOTYPE (MONO_HANDLE_RAW (ref_type)))
2840 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2844 klass = mono_class_from_mono_type (type);
2845 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2849 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2851 if (!IS_MONOTYPE (type))
2854 if (is_generic_parameter (type->type))
2855 return mono_type_get_generic_param_num (type->type);
2859 ICALL_EXPORT MonoGenericParamInfo *
2860 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionTypeHandle ref_type, MonoError *error)
2862 mono_error_init (error);
2863 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2864 return mono_generic_param_info (type->data.generic_param);
2867 ICALL_EXPORT MonoBoolean
2868 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionTypeHandle ref_type, MonoError *error)
2870 mono_error_init (error);
2871 MonoType *type = MONO_HANDLE_GETVAL(ref_type, type);
2872 return is_generic_parameter (type);
2875 ICALL_EXPORT MonoReflectionMethod*
2876 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2877 MonoReflectionMethod* generic)
2884 MonoReflectionMethod *ret = NULL;
2886 domain = ((MonoObject *)type)->vtable->domain;
2888 klass = mono_class_from_mono_type (type->type);
2889 mono_class_init_checked (klass, &error);
2890 if (mono_error_set_pending_exception (&error))
2894 while ((method = mono_class_get_methods (klass, &iter))) {
2895 if (method->token == generic->method->token) {
2896 ret = mono_method_get_object_checked (domain, method, klass, &error);
2897 if (mono_error_set_pending_exception (&error))
2905 ICALL_EXPORT MonoReflectionMethod *
2906 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2909 MonoType *type = ref_type->type;
2911 MonoReflectionMethod *ret = NULL;
2913 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2914 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2917 if (type->type == MONO_TYPE_VAR)
2920 method = mono_type_get_generic_param_owner (type)->owner.method;
2923 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2924 if (!mono_error_ok (&error))
2925 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2929 ICALL_EXPORT MonoBoolean
2930 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2932 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2936 ICALL_EXPORT MonoBoolean
2937 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2939 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2944 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2946 MonoDomain *domain = mono_domain_get ();
2947 MonoImage *image = method->method->klass->image;
2948 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2949 MonoTableInfo *tables = image->tables;
2950 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2951 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2952 guint32 im_cols [MONO_IMPLMAP_SIZE];
2953 guint32 scope_token;
2954 const char *import = NULL;
2955 const char *scope = NULL;
2957 if (image_is_dynamic (image)) {
2958 MonoReflectionMethodAux *method_aux =
2959 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2961 import = method_aux->dllentry;
2962 scope = method_aux->dll;
2965 if (!import || !scope) {
2966 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2971 if (piinfo->implmap_idx) {
2972 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2974 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2975 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2976 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2977 scope = mono_metadata_string_heap (image, scope_token);
2981 *flags = piinfo->piflags;
2982 *entry_point = mono_string_new (domain, import);
2983 *dll_name = mono_string_new (domain, scope);
2986 ICALL_EXPORT MonoReflectionMethod *
2987 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2989 MonoMethodInflated *imethod;
2991 MonoReflectionMethod *ret = NULL;
2994 if (method->method->is_generic)
2997 if (!method->method->is_inflated)
3000 imethod = (MonoMethodInflated *) method->method;
3002 result = imethod->declaring;
3003 /* Not a generic method. */
3004 if (!result->is_generic)
3007 if (image_is_dynamic (method->method->klass->image)) {
3008 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3009 MonoReflectionMethod *res;
3012 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3013 * the dynamic case as well ?
3015 mono_image_lock ((MonoImage*)image);
3016 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3017 mono_image_unlock ((MonoImage*)image);
3023 if (imethod->context.class_inst) {
3024 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3025 /*Generic methods gets the context of the GTD.*/
3026 if (mono_class_get_context (klass)) {
3027 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3028 if (!mono_error_ok (&error))
3033 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3035 if (!mono_error_ok (&error))
3036 mono_error_set_pending_exception (&error);
3040 ICALL_EXPORT gboolean
3041 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3043 return mono_method_signature (method->method)->generic_param_count != 0;
3046 ICALL_EXPORT gboolean
3047 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3049 return method->method->is_generic;
3052 ICALL_EXPORT MonoArray*
3053 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3056 MonoReflectionType *rt;
3061 domain = mono_object_domain (method);
3063 if (method->method->is_inflated) {
3064 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3067 count = inst->type_argc;
3068 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3069 if (mono_error_set_pending_exception (&error))
3072 for (i = 0; i < count; i++) {
3073 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3074 if (mono_error_set_pending_exception (&error))
3077 mono_array_setref (res, i, rt);
3084 count = mono_method_signature (method->method)->generic_param_count;
3085 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3086 if (mono_error_set_pending_exception (&error))
3089 for (i = 0; i < count; i++) {
3090 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3091 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3092 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3094 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3095 if (mono_error_set_pending_exception (&error))
3098 mono_array_setref (res, i, rt);
3104 ICALL_EXPORT MonoObject *
3105 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3109 * Invoke from reflection is supposed to always be a virtual call (the API
3110 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3111 * greater flexibility.
3113 MonoMethod *m = method->method;
3114 MonoMethodSignature *sig = mono_method_signature (m);
3117 void *obj = this_arg;
3121 if (mono_security_core_clr_enabled () &&
3122 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3123 mono_error_set_pending_exception (&error);
3127 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3128 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3129 mono_error_cleanup (&error); /* FIXME does this make sense? */
3130 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3135 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3136 if (!is_ok (&error)) {
3137 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3140 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3141 char *target_name = mono_type_get_full_name (m->klass);
3142 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3143 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3145 g_free (target_name);
3149 m = mono_object_get_virtual_method (this_arg, m);
3150 /* must pass the pointer to the value for valuetype methods */
3151 if (m->klass->valuetype)
3152 obj = mono_object_unbox (this_arg);
3153 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3154 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3159 if (sig->ret->byref) {
3160 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"));
3164 pcount = params? mono_array_length (params): 0;
3165 if (pcount != sig->param_count) {
3166 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3170 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3171 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."));
3175 image = m->klass->image;
3176 if (image->assembly->ref_only) {
3177 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."));
3181 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3182 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3186 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3190 intptr_t *lower_bounds;
3191 pcount = mono_array_length (params);
3192 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3193 /* Note: the synthetized array .ctors have int32 as argument type */
3194 for (i = 0; i < pcount; ++i)
3195 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3197 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3198 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3199 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3200 if (!mono_error_ok (&error)) {
3201 mono_error_set_pending_exception (&error);
3205 for (i = 0; i < mono_array_length (arr); ++i) {
3206 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3207 if (!mono_error_ok (&error)) {
3208 mono_error_set_pending_exception (&error);
3211 mono_array_setref_fast (arr, i, subarray);
3213 return (MonoObject*)arr;
3216 if (m->klass->rank == pcount) {
3217 /* Only lengths provided. */
3218 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3219 if (!mono_error_ok (&error)) {
3220 mono_error_set_pending_exception (&error);
3224 return (MonoObject*)arr;
3226 g_assert (pcount == (m->klass->rank * 2));
3227 /* The arguments are lower-bound-length pairs */
3228 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3230 for (i = 0; i < pcount / 2; ++i) {
3231 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3232 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3235 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3236 if (!mono_error_ok (&error)) {
3237 mono_error_set_pending_exception (&error);
3241 return (MonoObject*)arr;
3244 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3245 mono_error_set_pending_exception (&error);
3249 #ifndef DISABLE_REMOTING
3250 ICALL_EXPORT MonoObject *
3251 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3254 MonoDomain *domain = mono_object_domain (method);
3255 MonoMethod *m = method->method;
3256 MonoMethodSignature *sig = mono_method_signature (m);
3257 MonoArray *out_args;
3259 int i, j, outarg_count = 0;
3261 if (m->klass == mono_defaults.object_class) {
3262 if (!strcmp (m->name, "FieldGetter")) {
3263 MonoClass *k = this_arg->vtable->klass;
3267 /* If this is a proxy, then it must be a CBO */
3268 if (k == mono_defaults.transparent_proxy_class) {
3269 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3270 this_arg = tp->rp->unwrapped_server;
3271 g_assert (this_arg);
3272 k = this_arg->vtable->klass;
3275 name = mono_array_get (params, MonoString *, 1);
3276 str = mono_string_to_utf8_checked (name, &error);
3277 if (mono_error_set_pending_exception (&error))
3281 MonoClassField* field = mono_class_get_field_from_name (k, str);
3284 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3285 if (field_klass->valuetype) {
3286 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3287 if (mono_error_set_pending_exception (&error))
3290 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3292 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3293 if (mono_error_set_pending_exception (&error))
3295 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3296 mono_array_setref (out_args, 0, result);
3303 g_assert_not_reached ();
3305 } else if (!strcmp (m->name, "FieldSetter")) {
3306 MonoClass *k = this_arg->vtable->klass;
3312 /* If this is a proxy, then it must be a CBO */
3313 if (k == mono_defaults.transparent_proxy_class) {
3314 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3315 this_arg = tp->rp->unwrapped_server;
3316 g_assert (this_arg);
3317 k = this_arg->vtable->klass;
3320 name = mono_array_get (params, MonoString *, 1);
3321 str = mono_string_to_utf8_checked (name, &error);
3322 if (mono_error_set_pending_exception (&error))
3326 MonoClassField* field = mono_class_get_field_from_name (k, str);
3329 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3330 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3332 if (field_klass->valuetype) {
3333 size = mono_type_size (field->type, &align);
3334 g_assert (size == mono_class_value_size (field_klass, NULL));
3335 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3337 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3340 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3341 if (mono_error_set_pending_exception (&error))
3343 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3352 g_assert_not_reached ();
3357 for (i = 0; i < mono_array_length (params); i++) {
3358 if (sig->params [i]->byref)
3362 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3363 if (mono_error_set_pending_exception (&error))
3366 /* handle constructors only for objects already allocated */
3367 if (!strcmp (method->method->name, ".ctor"))
3368 g_assert (this_arg);
3370 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3371 g_assert (!method->method->klass->valuetype);
3372 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3373 if (mono_error_set_pending_exception (&error))
3376 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3377 if (sig->params [i]->byref) {
3379 arg = mono_array_get (params, gpointer, i);
3380 mono_array_setref (out_args, j, arg);
3385 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3392 read_enum_value (const char *mem, int type)
3395 case MONO_TYPE_BOOLEAN:
3397 return *(guint8*)mem;
3399 return *(gint8*)mem;
3400 case MONO_TYPE_CHAR:
3402 return read16 (mem);
3404 return (gint16) read16 (mem);
3406 return read32 (mem);
3408 return (gint32) read32 (mem);
3411 return read64 (mem);
3413 g_assert_not_reached ();
3419 write_enum_value (char *mem, int type, guint64 value)
3423 case MONO_TYPE_I1: {
3424 guint8 *p = (guint8*)mem;
3430 case MONO_TYPE_CHAR: {
3431 guint16 *p = (guint16 *)mem;
3436 case MONO_TYPE_I4: {
3437 guint32 *p = (guint32 *)mem;
3442 case MONO_TYPE_I8: {
3443 guint64 *p = (guint64 *)mem;
3448 g_assert_not_reached ();
3453 ICALL_EXPORT MonoObject *
3454 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3462 domain = mono_object_domain (enumType);
3463 enumc = mono_class_from_mono_type (enumType->type);
3465 mono_class_init_checked (enumc, &error);
3466 if (mono_error_set_pending_exception (&error))
3469 etype = mono_class_enum_basetype (enumc);
3471 res = mono_object_new_checked (domain, enumc, &error);
3472 if (mono_error_set_pending_exception (&error))
3474 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3479 ICALL_EXPORT MonoBoolean
3480 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3482 int size = mono_class_value_size (a->vtable->klass, NULL);
3483 guint64 a_val = 0, b_val = 0;
3485 memcpy (&a_val, mono_object_unbox (a), size);
3486 memcpy (&b_val, mono_object_unbox (b), size);
3488 return (a_val & b_val) == b_val;
3491 ICALL_EXPORT MonoObject *
3492 ves_icall_System_Enum_get_value (MonoObject *eobj)
3504 g_assert (eobj->vtable->klass->enumtype);
3506 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3507 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3508 if (mono_error_set_pending_exception (&error))
3510 dst = (char *)res + sizeof (MonoObject);
3511 src = (char *)eobj + sizeof (MonoObject);
3512 size = mono_class_value_size (enumc, NULL);
3514 memcpy (dst, src, size);
3519 ICALL_EXPORT MonoReflectionType *
3520 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3523 MonoReflectionType *ret;
3527 klass = mono_class_from_mono_type (type->type);
3528 mono_class_init_checked (klass, &error);
3529 if (mono_error_set_pending_exception (&error))
3532 etype = mono_class_enum_basetype (klass);
3534 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3538 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3539 mono_error_set_pending_exception (&error);
3545 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3547 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3548 gpointer odata = (char *)other + sizeof (MonoObject);
3549 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3550 g_assert (basetype);
3555 if (eobj->vtable->klass != other->vtable->klass)
3558 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3559 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3560 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3563 return me > other ? 1 : -1; \
3566 switch (basetype->type) {
3568 COMPARE_ENUM_VALUES (guint8);
3570 COMPARE_ENUM_VALUES (gint8);
3571 case MONO_TYPE_CHAR:
3573 COMPARE_ENUM_VALUES (guint16);
3575 COMPARE_ENUM_VALUES (gint16);
3577 COMPARE_ENUM_VALUES (guint32);
3579 COMPARE_ENUM_VALUES (gint32);
3581 COMPARE_ENUM_VALUES (guint64);
3583 COMPARE_ENUM_VALUES (gint64);
3587 #undef COMPARE_ENUM_VALUES
3588 /* indicates that the enum was of an unsupported unerlying type */
3593 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3595 gpointer data = (char *)eobj + sizeof (MonoObject);
3596 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3597 g_assert (basetype);
3599 switch (basetype->type) {
3600 case MONO_TYPE_I1: {
3601 gint8 value = *((gint8*)data);
3602 return ((int)value ^ (int)value << 8);
3605 return *((guint8*)data);
3606 case MONO_TYPE_CHAR:
3608 return *((guint16*)data);
3610 case MONO_TYPE_I2: {
3611 gint16 value = *((gint16*)data);
3612 return ((int)(guint16)value | (((int)value) << 16));
3615 return *((guint32*)data);
3617 return *((gint32*)data);
3619 case MONO_TYPE_I8: {
3620 gint64 value = *((gint64*)data);
3621 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3624 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3630 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3632 mono_error_init (error);
3633 HANDLE_FUNCTION_ENTER();
3634 guint64 field_value;
3636 MonoTypeEnum def_type;
3638 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3640 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3642 if (mono_field_is_deleted (field))
3644 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3647 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3649 p = mono_class_get_field_default_value (field, &def_type);
3650 /* len = */ mono_metadata_decode_blob_size (p, &p);
3652 field_value = read_enum_value (p, base_type);
3653 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3655 if (*previous_value > field_value)
3658 *previous_value = field_value;
3661 HANDLE_FUNCTION_RETURN();
3664 ICALL_EXPORT MonoBoolean
3665 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3667 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3668 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3669 guint j = 0, nvalues;
3671 MonoClassField *field;
3673 guint64 previous_value = 0;
3674 gboolean sorted = TRUE;
3676 mono_error_init (error);
3677 mono_class_init_checked (enumc, error);
3678 return_val_if_nok (error, FALSE);
3680 if (!enumc->enumtype) {
3681 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3685 base_type = mono_class_enum_basetype (enumc)->type;
3687 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3688 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3689 return_val_if_nok (error, FALSE);
3690 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3691 return_val_if_nok (error, FALSE);
3694 while ((field = mono_class_get_fields (enumc, &iter))) {
3695 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3699 return_val_if_nok (error, FALSE);
3705 BFLAGS_IgnoreCase = 1,
3706 BFLAGS_DeclaredOnly = 2,
3707 BFLAGS_Instance = 4,
3709 BFLAGS_Public = 0x10,
3710 BFLAGS_NonPublic = 0x20,
3711 BFLAGS_FlattenHierarchy = 0x40,
3712 BFLAGS_InvokeMethod = 0x100,
3713 BFLAGS_CreateInstance = 0x200,
3714 BFLAGS_GetField = 0x400,
3715 BFLAGS_SetField = 0x800,
3716 BFLAGS_GetProperty = 0x1000,
3717 BFLAGS_SetProperty = 0x2000,
3718 BFLAGS_ExactBinding = 0x10000,
3719 BFLAGS_SuppressChangeType = 0x20000,
3720 BFLAGS_OptionalParamBinding = 0x40000
3723 ICALL_EXPORT GPtrArray*
3724 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3727 MonoClass *startklass, *klass;
3730 int (*compare_func) (const char *s1, const char *s2) = NULL;
3731 MonoClassField *field;
3733 if (type->type->byref) {
3734 return g_ptr_array_new ();
3737 mono_error_init (&error);
3739 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3741 klass = startklass = mono_class_from_mono_type (type->type);
3743 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3746 if (mono_class_has_failure (klass)) {
3747 mono_error_set_for_class_failure (&error, klass);
3752 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3753 guint32 flags = mono_field_get_flags (field);
3755 if (mono_field_is_deleted_with_flags (field, flags))
3757 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3758 if (bflags & BFLAGS_Public)
3760 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3761 if (bflags & BFLAGS_NonPublic) {
3768 if (flags & FIELD_ATTRIBUTE_STATIC) {
3769 if (bflags & BFLAGS_Static)
3770 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3773 if (bflags & BFLAGS_Instance)
3780 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3783 g_ptr_array_add (ptr_array, field);
3785 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3791 g_ptr_array_free (ptr_array, TRUE);
3792 mono_error_set_pending_exception (&error);
3797 method_nonpublic (MonoMethod* method, gboolean start_klass)
3799 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3800 case METHOD_ATTRIBUTE_ASSEM:
3801 return (start_klass || mono_defaults.generic_ilist_class);
3802 case METHOD_ATTRIBUTE_PRIVATE:
3804 case METHOD_ATTRIBUTE_PUBLIC:
3812 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3815 MonoClass *startklass;
3819 /*FIXME, use MonoBitSet*/
3820 guint32 method_slots_default [8];
3821 guint32 *method_slots = NULL;
3822 int (*compare_func) (const char *s1, const char *s2) = NULL;
3824 array = g_ptr_array_new ();
3826 mono_error_init (error);
3829 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3831 /* An optimization for calls made from Delegate:CreateDelegate () */
3832 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3833 method = mono_get_delegate_invoke (klass);
3836 g_ptr_array_add (array, method);
3840 mono_class_setup_methods (klass);
3841 mono_class_setup_vtable (klass);
3842 if (mono_class_has_failure (klass))
3845 if (is_generic_parameter (&klass->byval_arg))
3846 nslots = mono_class_get_vtable_size (klass->parent);
3848 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3849 if (nslots >= sizeof (method_slots_default) * 8) {
3850 method_slots = g_new0 (guint32, nslots / 32 + 1);
3852 method_slots = method_slots_default;
3853 memset (method_slots, 0, sizeof (method_slots_default));
3856 mono_class_setup_methods (klass);
3857 mono_class_setup_vtable (klass);
3858 if (mono_class_has_failure (klass))
3862 while ((method = mono_class_get_methods (klass, &iter))) {
3864 if (method->slot != -1) {
3865 g_assert (method->slot < nslots);
3866 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3868 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3869 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3872 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3874 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3875 if (bflags & BFLAGS_Public)
3877 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3883 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3884 if (bflags & BFLAGS_Static)
3885 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3888 if (bflags & BFLAGS_Instance)
3896 if (compare_func (name, method->name))
3901 g_ptr_array_add (array, method);
3903 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3905 if (method_slots != method_slots_default)
3906 g_free (method_slots);
3911 if (method_slots != method_slots_default)
3912 g_free (method_slots);
3913 g_ptr_array_free (array, TRUE);
3915 g_assert (mono_class_has_failure (klass));
3916 mono_error_set_for_class_failure (error, klass);
3920 ICALL_EXPORT GPtrArray*
3921 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3924 GPtrArray *method_array;
3927 klass = mono_class_from_mono_type (type->type);
3928 if (type->type->byref) {
3929 return g_ptr_array_new ();
3932 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3933 mono_error_set_pending_exception (&error);
3934 return method_array;
3937 ICALL_EXPORT GPtrArray*
3938 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3940 MonoClass *startklass, *klass;
3943 gpointer iter = NULL;
3944 GPtrArray *res_array;
3947 if (type->type->byref) {
3948 return g_ptr_array_new ();
3951 klass = startklass = mono_class_from_mono_type (type->type);
3953 mono_class_setup_methods (klass);
3954 if (mono_class_has_failure (klass)) {
3955 mono_error_init (&error);
3956 mono_error_set_for_class_failure (&error, klass);
3957 mono_error_set_pending_exception (&error);
3961 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3964 while ((method = mono_class_get_methods (klass, &iter))) {
3966 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3968 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3969 if (bflags & BFLAGS_Public)
3972 if (bflags & BFLAGS_NonPublic)
3978 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3979 if (bflags & BFLAGS_Static)
3980 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3983 if (bflags & BFLAGS_Instance)
3989 g_ptr_array_add (res_array, method);
3996 property_hash (gconstpointer data)
3998 MonoProperty *prop = (MonoProperty*)data;
4000 return g_str_hash (prop->name);
4004 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4006 if (method1->slot != -1 && method1->slot == method2->slot)
4009 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4010 if (method1->is_inflated)
4011 method1 = ((MonoMethodInflated*) method1)->declaring;
4012 if (method2->is_inflated)
4013 method2 = ((MonoMethodInflated*) method2)->declaring;
4016 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4020 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4022 // Properties are hide-by-name-and-signature
4023 if (!g_str_equal (prop1->name, prop2->name))
4026 /* If we see a property in a generic method, we want to
4027 compare the generic signatures, not the inflated signatures
4028 because we might conflate two properties that were
4032 public T this[T t] { getter { return t; } } // method 1
4033 public U this[U u] { getter { return u; } } // method 2
4036 If we see int Foo<int,int>::Item[int] we need to know if
4037 the indexer came from method 1 or from method 2, and we
4038 shouldn't conflate them. (Bugzilla 36283)
4040 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4043 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4050 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4055 return method_nonpublic (accessor, start_klass);
4058 ICALL_EXPORT GPtrArray*
4059 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4062 MonoClass *startklass, *klass;
4067 int (*compare_func) (const char *s1, const char *s2) = NULL;
4069 GHashTable *properties = NULL;
4070 GPtrArray *res_array;
4072 if (type->type->byref) {
4073 return g_ptr_array_new ();
4076 mono_error_init (&error);
4078 klass = startklass = mono_class_from_mono_type (type->type);
4080 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4082 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4084 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4086 mono_class_setup_methods (klass);
4087 mono_class_setup_vtable (klass);
4088 if (mono_class_has_failure (klass)) {
4089 mono_error_set_for_class_failure (&error, klass);
4094 while ((prop = mono_class_get_properties (klass, &iter))) {
4100 flags = method->flags;
4103 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4104 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4105 if (bflags & BFLAGS_Public)
4107 } else if (bflags & BFLAGS_NonPublic) {
4108 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4109 property_accessor_nonpublic(prop->set, startklass == klass)) {
4116 if (flags & METHOD_ATTRIBUTE_STATIC) {
4117 if (bflags & BFLAGS_Static)
4118 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4121 if (bflags & BFLAGS_Instance)
4129 if (propname != NULL && compare_func (propname, prop->name))
4132 if (g_hash_table_lookup (properties, prop))
4135 g_ptr_array_add (res_array, prop);
4137 g_hash_table_insert (properties, prop, prop);
4139 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4142 g_hash_table_destroy (properties);
4149 g_hash_table_destroy (properties);
4150 g_ptr_array_free (res_array, TRUE);
4152 mono_error_set_pending_exception (&error);
4158 event_hash (gconstpointer data)
4160 MonoEvent *event = (MonoEvent*)data;
4162 return g_str_hash (event->name);
4166 event_equal (MonoEvent *event1, MonoEvent *event2)
4168 // Events are hide-by-name
4169 return g_str_equal (event1->name, event2->name);
4172 ICALL_EXPORT GPtrArray*
4173 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4176 MonoClass *startklass, *klass;
4181 int (*compare_func) (const char *s1, const char *s2) = NULL;
4182 GHashTable *events = NULL;
4183 GPtrArray *res_array;
4185 if (type->type->byref) {
4186 return g_ptr_array_new ();
4189 mono_error_init (&error);
4191 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4193 res_array = g_ptr_array_sized_new (4);
4195 klass = startklass = mono_class_from_mono_type (type->type);
4197 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4199 mono_class_setup_methods (klass);
4200 mono_class_setup_vtable (klass);
4201 if (mono_class_has_failure (klass)) {
4202 mono_error_set_for_class_failure (&error, klass);
4207 while ((event = mono_class_get_events (klass, &iter))) {
4209 method = event->add;
4211 method = event->remove;
4213 method = event->raise;
4215 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4216 if (bflags & BFLAGS_Public)
4218 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4219 if (bflags & BFLAGS_NonPublic)
4224 if (bflags & BFLAGS_NonPublic)
4230 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4231 if (bflags & BFLAGS_Static)
4232 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4235 if (bflags & BFLAGS_Instance)
4240 if (bflags & BFLAGS_Instance)
4245 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4248 if (g_hash_table_lookup (events, event))
4251 g_ptr_array_add (res_array, event);
4253 g_hash_table_insert (events, event, event);
4255 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4258 g_hash_table_destroy (events);
4264 g_hash_table_destroy (events);
4266 g_ptr_array_free (res_array, TRUE);
4268 mono_error_set_pending_exception (&error);
4272 ICALL_EXPORT GPtrArray *
4273 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4279 GPtrArray *res_array;
4281 if (type->type->byref) {
4282 return g_ptr_array_new ();
4285 klass = mono_class_from_mono_type (type->type);
4288 * If a nested type is generic, return its generic type definition.
4289 * Note that this means that the return value is essentially the set
4290 * of nested types of the generic type definition of @klass.
4292 * A note in MSDN claims that a generic type definition can have
4293 * nested types that aren't generic. In any case, the container of that
4294 * nested type would be the generic type definition.
4296 if (mono_class_is_ginst (klass))
4297 klass = mono_class_get_generic_class (klass)->container_class;
4299 res_array = g_ptr_array_new ();
4302 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4304 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4305 if (bflags & BFLAGS_Public)
4308 if (bflags & BFLAGS_NonPublic)
4314 if (str != NULL && strcmp (nested->name, str))
4317 g_ptr_array_add (res_array, &nested->byval_arg);
4324 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4326 HANDLE_FUNCTION_ENTER ();
4327 mono_error_init (error);
4328 MonoType *type = NULL;
4329 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4330 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4331 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4332 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4333 HANDLE_FUNCTION_RETURN_VAL (type);
4337 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4339 HANDLE_FUNCTION_ENTER ();
4340 mono_error_init (error);
4341 MonoType *type = NULL;
4342 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4343 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4344 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4345 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4346 HANDLE_FUNCTION_RETURN_VAL (type);
4349 ICALL_EXPORT MonoReflectionTypeHandle
4350 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4352 mono_error_init (error);
4354 MonoTypeNameParse info;
4355 gboolean type_resolve;
4357 /* On MS.NET, this does not fire a TypeResolve event */
4358 type_resolve = TRUE;
4359 char *str = mono_string_handle_to_utf8 (name, error);
4363 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4364 if (!mono_reflection_parse_type (str, &info)) {
4366 mono_reflection_free_type_info (&info);
4368 mono_error_set_argument (error, "name", "failed to parse the type");
4371 /*g_print ("failed parse\n");*/
4372 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4375 if (info.assembly.name) {
4377 mono_reflection_free_type_info (&info);
4379 /* 1.0 and 2.0 throw different exceptions */
4380 if (mono_defaults.generic_ilist_class)
4381 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4383 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4386 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4389 MonoType *type = NULL;
4390 if (!MONO_HANDLE_IS_NULL (module)) {
4391 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4393 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4394 if (!is_ok (error)) {
4396 mono_reflection_free_type_info (&info);
4402 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4403 if (assembly_is_dynamic (assembly)) {
4404 /* Enumerate all modules */
4405 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4406 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4409 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4410 MONO_HANDLE_GET (modules, abuilder, modules);
4411 if (!MONO_HANDLE_IS_NULL (modules)) {
4412 int n = mono_array_handle_length (modules);
4413 for (i = 0; i < n; ++i) {
4414 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4415 if (!is_ok (error)) {
4417 mono_reflection_free_type_info (&info);
4425 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4426 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4427 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4428 int n = mono_array_handle_length (loaded_modules);
4429 for (i = 0; i < n; ++i) {
4430 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4432 if (!is_ok (error)) {
4434 mono_reflection_free_type_info (&info);
4443 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4444 if (!is_ok (error)) {
4446 mono_reflection_free_type_info (&info);
4452 mono_reflection_free_type_info (&info);
4456 MonoError inner_error;
4457 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4458 mono_error_assert_ok (&inner_error);
4459 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4460 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4461 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4465 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4468 if (type->type == MONO_TYPE_CLASS) {
4469 MonoClass *klass = mono_type_get_class (type);
4471 /* need to report exceptions ? */
4472 if (throwOnError && mono_class_has_failure (klass)) {
4473 /* report SecurityException (or others) that occured when loading the assembly */
4474 mono_error_set_for_class_failure (error, klass);
4479 /* g_print ("got it\n"); */
4480 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4482 g_assert (!is_ok (error));
4483 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4487 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4490 gchar *shadow_ini_file;
4493 /* Check for shadow-copied assembly */
4494 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4495 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4497 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4498 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4504 g_free (shadow_ini_file);
4505 if (content != NULL) {
4508 *filename = content;
4515 ICALL_EXPORT MonoStringHandle
4516 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4518 mono_error_init (error);
4519 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4520 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4524 if (g_path_is_absolute (mass->image->name)) {
4525 absolute = g_strdup (mass->image->name);
4526 dirname = g_path_get_dirname (absolute);
4528 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4529 dirname = g_strdup (mass->basedir);
4532 replace_shadow_path (domain, dirname, &absolute);
4535 mono_icall_make_platform_path (absolute);
4539 uri = g_filename_to_uri (absolute, NULL, NULL);
4541 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4542 uri = g_strconcat (prepend, absolute, NULL);
4547 MonoStringHandle res;
4549 res = mono_string_new_handle (domain, uri, error);
4552 res = MONO_HANDLE_NEW (MonoString, NULL);
4557 ICALL_EXPORT MonoBoolean
4558 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4560 mono_error_init (error);
4561 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4563 return mass->in_gac;
4566 ICALL_EXPORT MonoReflectionAssemblyHandle
4567 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4570 MonoImageOpenStatus status;
4571 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4573 name = mono_string_handle_to_utf8 (mname, error);
4576 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4582 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4587 ICALL_EXPORT MonoStringHandle
4588 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4590 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4591 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4592 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4595 ICALL_EXPORT MonoBoolean
4596 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4598 mono_error_init (error);
4599 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4600 return assembly->ref_only;
4603 ICALL_EXPORT MonoStringHandle
4604 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4606 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4607 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4609 return mono_string_new_handle (domain, assembly->image->version, error);
4612 ICALL_EXPORT MonoReflectionMethodHandle
4613 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4615 mono_error_init (error);
4616 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4617 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4620 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4621 guint32 token = mono_image_get_entry_point (assembly->image);
4625 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4629 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4634 ICALL_EXPORT MonoReflectionModuleHandle
4635 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4637 mono_error_init (error);
4638 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4639 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4640 return mono_module_get_object_handle (domain, a->image, error);
4644 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4646 HANDLE_FUNCTION_ENTER ();
4647 mono_error_init (error);
4648 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4649 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4652 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4654 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4657 ICALL_EXPORT MonoArrayHandle
4658 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4660 mono_error_init (error);
4661 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4662 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4663 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4664 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4669 for (i = 0; i < table->rows; ++i) {
4670 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4675 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4678 ICALL_EXPORT MonoStringHandle
4679 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4681 char *guid = mono_runtime_get_aotid ();
4684 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4689 static MonoAssemblyName*
4690 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4692 mono_error_init (error);
4693 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4695 mono_assembly_get_assemblyref (image, i, aname);
4696 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4697 /* name and culture are pointers into the image tables, but we need
4698 * real malloc'd strings (so that we can g_free() them later from
4699 * Mono.RuntimeMarshal.FreeAssemblyName) */
4700 aname->name = g_strdup (aname->name);
4701 aname->culture = g_strdup (aname->culture);
4702 /* Don't need the hash value in managed */
4703 aname->hash_value = NULL;
4704 aname->hash_len = 0;
4705 g_assert (aname->public_key == NULL);
4707 /* note: this function doesn't return the codebase on purpose (i.e. it can
4708 be used under partial trust as path information isn't present). */
4712 ICALL_EXPORT GPtrArray*
4713 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4715 mono_error_init (error);
4716 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4717 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4718 MonoImage *image = ass->image;
4720 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4721 int count = t->rows;
4723 GPtrArray *result = g_ptr_array_sized_new (count);
4725 for (int i = 0; i < count; i++) {
4726 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4729 g_ptr_array_add (result, aname);
4734 /* move this in some file in mono/util/ */
4736 g_concat_dir_and_file (const char *dir, const char *file)
4738 g_return_val_if_fail (dir != NULL, NULL);
4739 g_return_val_if_fail (file != NULL, NULL);
4742 * If the directory name doesn't have a / on the end, we need
4743 * to add one so we get a proper path to the file
4745 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4746 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4748 return g_strconcat (dir, file, NULL);
4752 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4754 mono_error_init (error);
4755 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4756 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4757 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4759 guint32 cols [MONO_MANIFEST_SIZE];
4760 guint32 impl, file_idx;
4764 char *n = mono_string_handle_to_utf8 (name, error);
4765 return_val_if_nok (error, NULL);
4767 for (i = 0; i < table->rows; ++i) {
4768 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4769 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4770 if (strcmp (val, n) == 0)
4774 if (i == table->rows)
4777 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4780 * this code should only be called after obtaining the
4781 * ResourceInfo and handling the other cases.
4783 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4784 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4786 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4787 if (!is_ok (error) || !module)
4791 module = assembly->image;
4794 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4797 MONO_HANDLE_ASSIGN (ref_module, rm);
4799 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4803 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4805 HANDLE_FUNCTION_ENTER ();
4806 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4807 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4808 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4810 guint32 cols [MONO_MANIFEST_SIZE];
4811 guint32 file_cols [MONO_FILE_SIZE];
4815 gboolean result = FALSE;
4817 n = mono_string_handle_to_utf8 (name, error);
4821 for (i = 0; i < table->rows; ++i) {
4822 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4823 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4824 if (strcmp (val, n) == 0)
4828 if (i == table->rows)
4831 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4832 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4835 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4836 case MONO_IMPLEMENTATION_FILE:
4837 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4838 table = &assembly->image->tables [MONO_TABLE_FILE];
4839 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4840 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4841 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4842 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4843 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4845 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4848 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4849 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4850 mono_assembly_load_reference (assembly->image, i - 1);
4851 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4852 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4855 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4858 MONO_HANDLE_SET (info, assembly, assm_obj);
4860 /* Obtain info recursively */
4861 get_manifest_resource_info_internal (assm_obj, name, info, error);
4864 guint32 location = MONO_HANDLE_GETVAL (info, location);
4865 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4866 MONO_HANDLE_SETVAL (info, location, guint32, location);
4869 case MONO_IMPLEMENTATION_EXP_TYPE:
4870 g_assert_not_reached ();
4877 HANDLE_FUNCTION_RETURN_VAL (result);
4880 ICALL_EXPORT gboolean
4881 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4883 mono_error_init (error);
4884 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4888 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4890 HANDLE_FUNCTION_ENTER();
4891 mono_error_init (error);
4892 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4893 char *n = g_concat_dir_and_file (assembly->basedir, val);
4894 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4898 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4900 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4903 ICALL_EXPORT MonoObjectHandle
4904 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4906 mono_error_init (error);
4907 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4908 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4909 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4912 /* check hash if needed */
4913 if (!MONO_HANDLE_IS_NULL(name)) {
4914 char *n = mono_string_handle_to_utf8 (name, error);
4918 for (i = 0; i < table->rows; ++i) {
4919 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4920 if (strcmp (val, n) == 0) {
4922 n = g_concat_dir_and_file (assembly->basedir, val);
4923 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4927 return MONO_HANDLE_CAST (MonoObject, fn);
4935 for (i = 0; i < table->rows; ++i) {
4936 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4940 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4945 for (i = 0; i < table->rows; ++i) {
4946 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4947 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4952 return MONO_HANDLE_CAST (MonoObject, result);
4958 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4960 HANDLE_FUNCTION_ENTER ();
4961 mono_error_init (error);
4963 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4967 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4972 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4976 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4978 HANDLE_FUNCTION_ENTER ();
4979 mono_error_init (error);
4981 guint32 cols [MONO_FILE_SIZE];
4982 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4983 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4984 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4987 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4989 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4993 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4994 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4997 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
5000 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5004 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5007 ICALL_EXPORT MonoArrayHandle
5008 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5010 mono_error_init (error);
5011 MonoDomain *domain = mono_domain_get();
5012 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5014 int i, j, file_count = 0;
5015 MonoImage **modules;
5016 guint32 module_count, real_module_count;
5017 MonoTableInfo *table;
5018 MonoImage *image = assembly->image;
5020 g_assert (image != NULL);
5021 g_assert (!assembly_is_dynamic (assembly));
5023 table = &image->tables [MONO_TABLE_FILE];
5024 file_count = table->rows;
5026 modules = image->modules;
5027 module_count = image->module_count;
5029 real_module_count = 0;
5030 for (i = 0; i < module_count; ++i)
5032 real_module_count ++;
5034 klass = mono_class_get_module_class ();
5035 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5039 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5043 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5046 for (i = 0; i < module_count; ++i)
5047 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5050 for (i = 0; i < file_count; ++i, ++j) {
5051 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5057 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5060 ICALL_EXPORT MonoReflectionMethodHandle
5061 ves_icall_GetCurrentMethod (MonoError *error)
5063 mono_error_init (error);
5065 MonoMethod *m = mono_method_get_last_managed ();
5068 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5069 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5072 while (m->is_inflated)
5073 m = ((MonoMethodInflated*)m)->declaring;
5075 return mono_method_get_object_handle (mono_domain_get (), m, NULL, error);
5080 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5083 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5086 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5087 //method is inflated, we should inflate it on the other class
5088 MonoGenericContext ctx;
5089 ctx.method_inst = inflated->context.method_inst;
5090 ctx.class_inst = inflated->context.class_inst;
5091 if (mono_class_is_ginst (klass))
5092 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5093 else if (mono_class_is_gtd (klass))
5094 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5095 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5096 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5100 mono_class_setup_methods (method->klass);
5101 if (mono_class_has_failure (method->klass))
5103 int mcount = mono_class_get_method_count (method->klass);
5104 for (i = 0; i < mcount; ++i) {
5105 if (method->klass->methods [i] == method) {
5110 mono_class_setup_methods (klass);
5111 if (mono_class_has_failure (klass))
5113 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5114 return klass->methods [offset];
5117 ICALL_EXPORT MonoReflectionMethodHandle
5118 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check, MonoError *error)
5120 mono_error_init (error);
5122 if (type && generic_check) {
5123 klass = mono_class_from_mono_type (type);
5124 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5125 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5127 if (method->klass != klass) {
5128 method = mono_method_get_equivalent_method (method, klass);
5130 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5133 klass = mono_class_from_mono_type (type);
5135 klass = method->klass;
5136 return mono_method_get_object_handle (mono_domain_get (), method, klass, error);
5139 ICALL_EXPORT MonoReflectionMethodBodyHandle
5140 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method, MonoError *error)
5142 mono_error_init (error);
5143 return mono_method_body_get_object_handle (mono_domain_get (), method, error);
5146 ICALL_EXPORT MonoReflectionAssemblyHandle
5147 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5149 mono_error_init (error);
5151 MonoMethod *dest = NULL;
5152 mono_stack_walk_no_il (get_executing, &dest);
5154 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5158 ICALL_EXPORT MonoReflectionAssemblyHandle
5159 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5161 mono_error_init (error);
5163 MonoDomain* domain = mono_domain_get ();
5165 if (!domain->entry_assembly)
5166 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5168 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5171 ICALL_EXPORT MonoReflectionAssemblyHandle
5172 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5174 mono_error_init (error);
5179 mono_stack_walk_no_il (get_executing, &dest);
5181 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5185 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5186 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5188 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5191 ICALL_EXPORT MonoStringHandle
5192 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5193 gboolean assembly_qualified, MonoError *error)
5195 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5196 MonoType *type = MONO_HANDLE_RAW (object)->type;
5197 MonoTypeNameFormat format;
5198 MonoStringHandle res;
5202 format = assembly_qualified ?
5203 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5204 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5206 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5208 name = mono_type_get_name_full (type, format);
5210 return NULL_HANDLE_STRING;
5212 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5214 return NULL_HANDLE_STRING;
5217 res = mono_string_new_handle (domain, name, error);
5224 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5227 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5229 mono_class_init_checked (klass, &error);
5230 mono_error_set_pending_exception (&error);
5231 return mono_security_core_clr_class_level (klass);
5235 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5237 MonoClassField *field = rfield->field;
5238 return mono_security_core_clr_field_level (field, TRUE);
5242 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5244 MonoMethod *method = rfield->method;
5245 return mono_security_core_clr_method_level (method, TRUE);
5248 ICALL_EXPORT MonoStringHandle
5249 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5251 mono_error_init (error);
5252 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5253 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5256 name = mono_stringify_assembly_name (&mass->aname);
5257 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5262 ICALL_EXPORT MonoAssemblyName *
5263 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5265 return &mass->aname;
5269 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5272 MonoImageOpenStatus status = MONO_IMAGE_OK;
5273 char *codebase = NULL;
5278 mono_error_init (error);
5280 filename = mono_string_handle_to_utf8 (fname, error);
5281 return_if_nok (error);
5283 dirname = g_path_get_dirname (filename);
5284 replace_shadow_path (mono_domain_get (), dirname, &filename);
5287 image = mono_image_open (filename, &status);
5290 if (status == MONO_IMAGE_IMAGE_INVALID)
5291 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5293 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5298 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5300 mono_image_close (image);
5302 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5306 if (filename != NULL && *filename != '\0') {
5309 codebase = g_strdup (filename);
5311 mono_icall_make_platform_path (codebase);
5313 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5315 result = g_strconcat (prepend, codebase, NULL);
5319 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5322 mono_image_close (image);
5326 ICALL_EXPORT MonoBoolean
5327 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5328 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5330 mono_error_init (error);
5331 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5332 MonoBoolean result = FALSE;
5333 MonoDeclSecurityEntry entry;
5335 /* SecurityAction.RequestMinimum */
5336 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5337 *minimum = entry.blob;
5338 *minLength = entry.size;
5341 /* SecurityAction.RequestOptional */
5342 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5343 *optional = entry.blob;
5344 *optLength = entry.size;
5347 /* SecurityAction.RequestRefuse */
5348 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5349 *refused = entry.blob;
5350 *refLength = entry.size;
5358 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5360 guint32 attrs, visibility;
5362 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5363 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5364 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5367 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5373 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5375 mono_error_init (error);
5376 HANDLE_FUNCTION_ENTER ();
5377 MonoError klass_error;
5378 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5381 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5382 return_if_nok (error);
5384 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5386 MonoException *ex = mono_error_convert_to_exception (error);
5387 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5389 HANDLE_FUNCTION_RETURN ();
5392 static MonoArrayHandle
5393 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5395 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5398 mono_error_init (error);
5400 /* we start the count from 1 because we skip the special type <Module> */
5403 for (i = 1; i < tdef->rows; ++i) {
5404 if (mono_module_type_is_visible (tdef, image, i + 1))
5408 count = tdef->rows - 1;
5410 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5411 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5412 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5413 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5415 for (i = 1; i < tdef->rows; ++i) {
5416 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5417 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5418 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5427 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5429 HANDLE_FUNCTION_ENTER ();
5430 mono_error_init (error);
5431 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5432 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5436 /* Append the new types to the end of the array */
5437 if (mono_array_handle_length (res2) > 0) {
5440 len1 = mono_array_handle_length (res);
5441 len2 = mono_array_handle_length (res2);
5443 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5447 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5448 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5449 MONO_HANDLE_ASSIGN (res, res3);
5451 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5455 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5456 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5457 MONO_HANDLE_ASSIGN (exceptions, ex3);
5460 HANDLE_FUNCTION_RETURN ();
5464 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5466 HANDLE_FUNCTION_ENTER ();
5467 MonoError unboxed_error;
5468 mono_error_init (&unboxed_error);
5469 mono_error_set_for_class_failure (&unboxed_error, klass);
5471 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5472 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5473 HANDLE_FUNCTION_RETURN ();
5476 ICALL_EXPORT MonoArrayHandle
5477 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5479 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5482 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5483 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5485 g_assert (!assembly_is_dynamic (assembly));
5486 MonoImage *image = assembly->image;
5487 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5488 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5489 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5491 /* Append data from all modules in the assembly */
5492 for (i = 0; i < table->rows; ++i) {
5493 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5494 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5495 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5498 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5499 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5504 /* the ReflectionTypeLoadException must have all the types (Types property),
5505 * NULL replacing types which throws an exception. The LoaderException must
5506 * contain all exceptions for NULL items.
5509 int len = mono_array_handle_length (res);
5513 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5514 for (i = 0; i < len; i++) {
5515 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5517 if (!MONO_HANDLE_IS_NULL (t)) {
5518 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5519 if ((klass != NULL) && mono_class_has_failure (klass)) {
5520 /* keep the class in the list */
5521 list = g_list_append (list, klass);
5522 /* and replace Type with NULL */
5523 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5530 if (list || ex_count) {
5532 int j, length = g_list_length (list) + ex_count;
5534 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5535 if (!is_ok (error)) {
5537 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5539 /* Types for which mono_class_get_checked () succeeded */
5540 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5541 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5542 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5544 /* Types for which it don't */
5545 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5546 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5547 if (!MONO_HANDLE_IS_NULL (exc)) {
5548 g_assert (i < length);
5549 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5556 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5557 if (!is_ok (error)) {
5558 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5560 mono_error_set_exception_handle (error, exc);
5561 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5568 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5570 mono_assembly_name_free (aname);
5575 ICALL_EXPORT gboolean
5576 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5578 *is_version_definited = *is_token_defined = FALSE;
5580 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5583 ICALL_EXPORT MonoReflectionTypeHandle
5584 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5586 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5587 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5592 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5594 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5595 /* These images do not have a global type */
5598 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5602 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5608 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5610 /*if (module->image)
5611 mono_image_close (module->image);*/
5614 ICALL_EXPORT MonoStringHandle
5615 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5617 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5618 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5621 return mono_string_new_handle (domain, image->guid, error);
5625 static inline gpointer
5626 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5628 return (gpointer) (-1);
5630 #endif /* HOST_WIN32 */
5632 ICALL_EXPORT gpointer
5633 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5635 return mono_icall_module_get_hinstance (module);
5639 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5641 if (image_is_dynamic (image)) {
5642 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5643 *pe_kind = dyn->pe_kind;
5644 *machine = dyn->machine;
5647 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5648 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5653 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5655 return (image->md_version_major << 16) | (image->md_version_minor);
5658 ICALL_EXPORT MonoArrayHandle
5659 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5661 mono_error_init (error);
5663 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5664 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5667 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5670 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5671 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5672 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5674 int n = mono_array_handle_length (exceptions);
5675 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5676 for (int i = 0; i < n; ++i) {
5677 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5678 if (!MONO_HANDLE_IS_NULL (ex)) {
5679 mono_error_set_exception_handle (error, ex);
5680 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5688 mono_memberref_is_method (MonoImage *image, guint32 token)
5690 if (!image_is_dynamic (image)) {
5691 guint32 cols [MONO_MEMBERREF_SIZE];
5693 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5694 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5695 mono_metadata_decode_blob_size (sig, &sig);
5696 return (*sig != 0x6);
5699 MonoClass *handle_class;
5701 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5702 mono_error_cleanup (&error); /* just probing, ignore error */
5706 return mono_defaults.methodhandle_class == handle_class;
5710 static MonoGenericInst *
5711 get_generic_inst_from_array_handle (MonoArrayHandle type_args)
5713 int type_argc = mono_array_handle_length (type_args);
5714 int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
5716 MonoGenericInst *ginst = (MonoGenericInst *)g_alloca (size);
5717 memset (ginst, 0, sizeof (MonoGenericInst));
5718 ginst->type_argc = type_argc;
5719 for (int i = 0; i < type_argc; i++) {
5720 MONO_HANDLE_ARRAY_GETVAL (ginst->type_argv[i], type_args, MonoType*, i);
5722 ginst->is_open = FALSE;
5723 for (int i = 0; i < type_argc; i++) {
5724 if (mono_class_is_open_constructed_type (ginst->type_argv[i])) {
5725 ginst->is_open = TRUE;
5730 return mono_metadata_get_canonical_generic_inst (ginst);
5734 init_generic_context_from_args_handles (MonoGenericContext *context, MonoArrayHandle type_args, MonoArrayHandle method_args)
5736 if (!MONO_HANDLE_IS_NULL (type_args)) {
5737 context->class_inst = get_generic_inst_from_array_handle (type_args);
5739 context->class_inst = NULL;
5741 if (!MONO_HANDLE_IS_NULL (method_args)) {
5742 context->method_inst = get_generic_inst_from_array_handle (method_args);
5744 context->method_inst = NULL;
5750 module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5752 HANDLE_FUNCTION_ENTER ();
5753 mono_error_init (error);
5754 MonoType *result = NULL;
5756 int table = mono_metadata_token_table (token);
5757 int index = mono_metadata_token_index (token);
5758 MonoGenericContext context;
5760 *resolve_error = ResolveTokenError_Other;
5762 /* Validate token */
5763 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5764 (table != MONO_TABLE_TYPESPEC)) {
5765 *resolve_error = ResolveTokenError_BadTable;
5769 if (image_is_dynamic (image)) {
5770 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5771 MonoError inner_error;
5772 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5773 mono_error_cleanup (&inner_error);
5774 result = klass ? &klass->byval_arg : NULL;
5778 init_generic_context_from_args_handles (&context, type_args, method_args);
5779 MonoError inner_error;
5780 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5781 mono_error_cleanup (&inner_error);
5782 result = klass ? &klass->byval_arg : NULL;
5786 if ((index <= 0) || (index > image->tables [table].rows)) {
5787 *resolve_error = ResolveTokenError_OutOfRange;
5791 init_generic_context_from_args_handles (&context, type_args, method_args);
5792 klass = mono_class_get_checked (image, token, error);
5794 klass = mono_class_inflate_generic_class_checked (klass, &context, error);
5799 result = &klass->byval_arg;
5801 HANDLE_FUNCTION_RETURN_VAL (result);
5804 ICALL_EXPORT MonoType*
5805 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5807 return module_resolve_type_token (image, token, type_args, method_args, resolve_error, error);
5811 module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5813 HANDLE_FUNCTION_ENTER ();
5814 mono_error_init (error);
5815 MonoMethod *method = NULL;
5816 int table = mono_metadata_token_table (token);
5817 int index = mono_metadata_token_index (token);
5818 MonoGenericContext context;
5820 *resolve_error = ResolveTokenError_Other;
5822 /* Validate token */
5823 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5824 (table != MONO_TABLE_MEMBERREF)) {
5825 *resolve_error = ResolveTokenError_BadTable;
5829 if (image_is_dynamic (image)) {
5830 if (table == MONO_TABLE_METHOD) {
5831 MonoError inner_error;
5832 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5833 mono_error_cleanup (&inner_error);
5837 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5838 *resolve_error = ResolveTokenError_BadTable;
5842 init_generic_context_from_args_handles (&context, type_args, method_args);
5843 MonoError inner_error;
5844 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5845 mono_error_cleanup (&inner_error);
5849 if ((index <= 0) || (index > image->tables [table].rows)) {
5850 *resolve_error = ResolveTokenError_OutOfRange;
5853 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5854 *resolve_error = ResolveTokenError_BadTable;
5858 init_generic_context_from_args_handles (&context, type_args, method_args);
5859 method = mono_get_method_checked (image, token, NULL, &context, error);
5862 HANDLE_FUNCTION_RETURN_VAL (method);
5865 ICALL_EXPORT MonoMethod*
5866 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5868 return module_resolve_method_token (image, token, type_args, method_args, resolve_error, error);
5871 ICALL_EXPORT MonoString*
5872 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5875 int index = mono_metadata_token_index (token);
5877 *resolve_error = ResolveTokenError_Other;
5879 /* Validate token */
5880 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5881 *resolve_error = ResolveTokenError_BadTable;
5885 if (image_is_dynamic (image)) {
5886 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5887 mono_error_cleanup (&error);
5891 if ((index <= 0) || (index >= image->heap_us.size)) {
5892 *resolve_error = ResolveTokenError_OutOfRange;
5896 /* FIXME: What to do if the index points into the middle of a string ? */
5898 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5899 mono_error_set_pending_exception (&error);
5903 static MonoClassField*
5904 module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5906 HANDLE_FUNCTION_ENTER ();
5908 int table = mono_metadata_token_table (token);
5909 int index = mono_metadata_token_index (token);
5910 MonoGenericContext context;
5911 MonoClassField *field = NULL;
5913 mono_error_init (error);
5914 *resolve_error = ResolveTokenError_Other;
5916 /* Validate token */
5917 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5918 *resolve_error = ResolveTokenError_BadTable;
5922 if (image_is_dynamic (image)) {
5923 if (table == MONO_TABLE_FIELD) {
5924 MonoError inner_error;
5925 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5926 mono_error_cleanup (&inner_error);
5930 if (mono_memberref_is_method (image, token)) {
5931 *resolve_error = ResolveTokenError_BadTable;
5935 init_generic_context_from_args_handles (&context, type_args, method_args);
5936 MonoError inner_error;
5937 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5938 mono_error_cleanup (&inner_error);
5942 if ((index <= 0) || (index > image->tables [table].rows)) {
5943 *resolve_error = ResolveTokenError_OutOfRange;
5946 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5947 *resolve_error = ResolveTokenError_BadTable;
5951 init_generic_context_from_args_handles (&context, type_args, method_args);
5952 field = mono_field_from_token_checked (image, token, &klass, &context, error);
5955 HANDLE_FUNCTION_RETURN_VAL (field);
5958 ICALL_EXPORT MonoClassField*
5959 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5961 return module_resolve_field_token (image, token, type_args, method_args, resolve_error, error);
5964 ICALL_EXPORT MonoObjectHandle
5965 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *error, MonoError *merror)
5967 int table = mono_metadata_token_table (token);
5969 mono_error_init (merror);
5970 *error = ResolveTokenError_Other;
5973 case MONO_TABLE_TYPEDEF:
5974 case MONO_TABLE_TYPEREF:
5975 case MONO_TABLE_TYPESPEC: {
5976 MonoType *t = module_resolve_type_token (image, token, type_args, method_args, error, merror);
5978 return MONO_HANDLE_CAST (MonoObject, mono_type_get_object_handle (mono_domain_get (), t, merror));
5983 case MONO_TABLE_METHOD:
5984 case MONO_TABLE_METHODSPEC: {
5985 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
5987 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
5991 case MONO_TABLE_FIELD: {
5992 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
5994 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
5999 case MONO_TABLE_MEMBERREF:
6000 if (mono_memberref_is_method (image, token)) {
6001 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
6003 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
6008 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
6010 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6018 *error = ResolveTokenError_BadTable;
6024 ICALL_EXPORT MonoArrayHandle
6025 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error, MonoError *error)
6027 mono_error_init (error);
6028 int table = mono_metadata_token_table (token);
6029 int idx = mono_metadata_token_index (token);
6030 MonoTableInfo *tables = image->tables;
6034 *resolve_error = ResolveTokenError_OutOfRange;
6036 /* FIXME: Support other tables ? */
6037 if (table != MONO_TABLE_STANDALONESIG)
6038 return MONO_HANDLE_CAST (MonoArray, NULL);
6040 if (image_is_dynamic (image))
6041 return MONO_HANDLE_CAST (MonoArray, NULL);
6043 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6044 return MONO_HANDLE_CAST (MonoArray, NULL);
6046 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6048 ptr = mono_metadata_blob_heap (image, sig);
6049 len = mono_metadata_decode_blob_size (ptr, &ptr);
6051 MonoArrayHandle res = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, len, error);
6053 return MONO_HANDLE_CAST (MonoArray, NULL);
6055 gpointer array_base = MONO_ARRAY_HANDLE_PIN (res, guint8, 0, &h);
6056 memcpy (array_base, ptr, len);
6057 mono_gchandle_free (h);
6061 ICALL_EXPORT MonoBoolean
6062 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionTypeHandle ref_type, MonoError *error)
6064 mono_error_init (error);
6065 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6067 MonoBoolean res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6073 check_for_invalid_type (MonoClass *klass, MonoError *error)
6077 mono_error_init (error);
6079 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6082 name = mono_type_get_full_name (klass);
6083 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6085 ICALL_EXPORT MonoReflectionType *
6086 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6089 MonoReflectionType *ret;
6090 MonoClass *klass, *aklass;
6092 klass = mono_class_from_mono_type (type->type);
6093 check_for_invalid_type (klass, &error);
6094 if (mono_error_set_pending_exception (&error))
6097 if (rank == 0) //single dimentional array
6098 aklass = mono_array_class_get (klass, 1);
6100 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6102 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6103 mono_error_set_pending_exception (&error);
6108 ICALL_EXPORT MonoReflectionType *
6109 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6112 MonoReflectionType *ret;
6115 klass = mono_class_from_mono_type (type->type);
6116 mono_class_init_checked (klass, &error);
6117 if (mono_error_set_pending_exception (&error))
6120 check_for_invalid_type (klass, &error);
6121 if (mono_error_set_pending_exception (&error))
6124 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6125 mono_error_set_pending_exception (&error);
6130 ICALL_EXPORT MonoReflectionType *
6131 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6134 MonoReflectionType *ret;
6135 MonoClass *klass, *pklass;
6137 klass = mono_class_from_mono_type (type->type);
6138 mono_class_init_checked (klass, &error);
6139 if (mono_error_set_pending_exception (&error))
6141 check_for_invalid_type (klass, &error);
6142 if (mono_error_set_pending_exception (&error))
6145 pklass = mono_ptr_class_get (type->type);
6147 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6148 mono_error_set_pending_exception (&error);
6153 ICALL_EXPORT MonoObject *
6154 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6155 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6158 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6159 MonoObject *delegate;
6161 MonoMethod *method = info->method;
6162 MonoMethodSignature *sig = mono_method_signature(method);
6164 mono_class_init_checked (delegate_class, &error);
6165 if (mono_error_set_pending_exception (&error))
6168 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6169 /* FIXME improve this exception message */
6170 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6172 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6173 mono_error_set_pending_exception (&error);
6177 if (mono_security_core_clr_enabled ()) {
6178 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6179 if (throwOnBindFailure)
6180 mono_error_set_pending_exception (&error);
6182 mono_error_cleanup (&error);
6187 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6188 if (!method->is_inflated) {
6189 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"));
6194 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6195 if (mono_error_set_pending_exception (&error))
6198 if (method_is_dynamic (method)) {
6199 /* Creating a trampoline would leak memory */
6200 func = mono_compile_method_checked (method, &error);
6201 if (mono_error_set_pending_exception (&error))
6204 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6205 method = mono_object_get_virtual_method (target, method);
6206 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6207 if (mono_error_set_pending_exception (&error))
6209 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6212 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6213 if (mono_error_set_pending_exception (&error))
6218 ICALL_EXPORT MonoMulticastDelegate *
6219 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6222 MonoMulticastDelegate *ret;
6224 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6226 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6227 if (mono_error_set_pending_exception (&error))
6230 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6235 ICALL_EXPORT MonoReflectionMethod*
6236 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6238 MonoReflectionMethod *ret = NULL;
6240 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6241 mono_error_set_pending_exception (&error);
6247 static inline gint32
6248 mono_array_get_byte_length (MonoArray *array)
6254 klass = array->obj.vtable->klass;
6256 if (array->bounds == NULL)
6257 length = array->max_length;
6260 for (i = 0; i < klass->rank; ++ i)
6261 length *= array->bounds [i].length;
6264 switch (klass->element_class->byval_arg.type) {
6267 case MONO_TYPE_BOOLEAN:
6271 case MONO_TYPE_CHAR:
6279 return length * sizeof (gpointer);
6290 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6292 return mono_array_get_byte_length (array);
6296 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6298 return mono_array_get (array, gint8, idx);
6302 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6304 mono_array_set (array, gint8, idx, value);
6307 ICALL_EXPORT MonoBoolean
6308 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6310 guint8 *src_buf, *dest_buf;
6313 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6317 g_assert (count >= 0);
6319 /* This is called directly from the class libraries without going through the managed wrapper */
6320 MONO_CHECK_ARG_NULL (src, FALSE);
6321 MONO_CHECK_ARG_NULL (dest, FALSE);
6323 /* watch out for integer overflow */
6324 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6327 src_buf = (guint8 *)src->vector + src_offset;
6328 dest_buf = (guint8 *)dest->vector + dest_offset;
6331 memcpy (dest_buf, src_buf, count);
6333 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6338 #ifndef DISABLE_REMOTING
6339 ICALL_EXPORT MonoObject *
6340 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6343 MonoDomain *domain = mono_object_domain (this_obj);
6345 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6346 MonoTransparentProxy *tp;
6350 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6351 if (mono_error_set_pending_exception (&error))
6354 tp = (MonoTransparentProxy*) res;
6356 MONO_OBJECT_SETREF (tp, rp, rp);
6357 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6358 klass = mono_class_from_mono_type (type);
6360 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6361 mono_class_setup_vtable (klass);
6362 if (mono_class_has_failure (klass)) {
6363 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6367 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6368 if (mono_error_set_pending_exception (&error))
6370 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6371 if (mono_error_set_pending_exception (&error))
6374 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6375 if (mono_error_set_pending_exception (&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);