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/w32socket.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 (mono_class_is_transparent_proxy (klass)) {
1223 MonoTransparentProxyHandle proxy_obj = MONO_HANDLE_CAST (MonoTransparentProxy, obj);
1224 MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (proxy_obj, remote_class);
1225 MonoType *proxy_type = &remote_class->proxy_class->byval_arg;
1226 return mono_type_get_object_handle (domain, proxy_type, error);
1229 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
1233 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1235 MonoMethod **dest = (MonoMethod **)data;
1237 /* skip unmanaged frames */
1242 if (!strcmp (m->klass->name_space, "System.Reflection"))
1251 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1253 MonoMethod **dest = (MonoMethod **)data;
1255 /* skip unmanaged frames */
1259 if (m->wrapper_type != MONO_WRAPPER_NONE)
1267 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1278 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1280 MonoMethod **dest = (MonoMethod **)data;
1282 /* skip unmanaged frames */
1286 if (m->wrapper_type != MONO_WRAPPER_NONE)
1294 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1295 || (!strcmp (m->klass->name_space, "System"))))
1305 static MonoReflectionTypeHandle
1306 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1308 MonoMethod *m, *dest;
1310 MonoType *type = NULL;
1311 MonoAssembly *assembly = NULL;
1312 gboolean type_resolve = FALSE;
1313 MonoImage *rootimage = NULL;
1315 mono_error_init (error);
1318 * We must compute the calling assembly as type loading must happen under a metadata context.
1319 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1320 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1322 m = mono_method_get_last_managed ();
1324 if (m && m->klass->image != mono_defaults.corlib) {
1325 /* Happens with inlining */
1327 /* Ugly hack: type_from_parsed_name is called from
1328 * System.Type.internal_from_name, which is called most
1329 * directly from System.Type.GetType(string,bool,bool) but
1330 * also indirectly from places such as
1331 * System.Type.GetType(string,func,func) (via
1332 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1333 * so we need to skip over all of those to find the true caller.
1335 * It would be nice if we had stack marks.
1337 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1343 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1344 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1345 * to crash. This only seems to happen in some strange remoting
1346 * scenarios and I was unable to figure out what's happening there.
1347 * Dec 10, 2005 - Martin.
1351 assembly = dest->klass->image->assembly;
1352 type_resolve = TRUE;
1353 rootimage = assembly->image;
1355 g_warning (G_STRLOC);
1357 *caller_assembly = assembly;
1359 if (info->assembly.name)
1360 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1363 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1364 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1370 // Say we're looking for System.Generic.Dict<int, Local>
1371 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1372 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1373 // is messed up when we go to construct the Local as the type arg...
1375 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1376 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1377 if (!info->assembly.name && !type) {
1379 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1383 if (assembly && !type && type_resolve) {
1384 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1385 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1393 return mono_type_get_object_handle (mono_domain_get (), type, error);
1395 return MONO_HANDLE_NEW (MonoReflectionType, NULL);
1398 ICALL_EXPORT MonoReflectionTypeHandle
1399 ves_icall_System_Type_internal_from_name (MonoStringHandle name,
1400 MonoBoolean throwOnError,
1401 MonoBoolean ignoreCase,
1404 mono_error_init (error);
1405 MonoTypeNameParse info;
1407 MonoAssembly *caller_assembly;
1408 MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1410 char *str = mono_string_handle_to_utf8 (name, error);
1414 parsedOk = mono_reflection_parse_type (str, &info);
1416 /* mono_reflection_parse_type() mangles the string */
1418 mono_reflection_free_type_info (&info);
1420 mono_error_set_argument (error, "typeName", "failed parse: %s", str);
1424 MONO_HANDLE_ASSIGN (type, type_from_parsed_name (&info, ignoreCase, &caller_assembly, error));
1426 if (!is_ok (error)) {
1427 mono_reflection_free_type_info (&info);
1431 if (MONO_HANDLE_IS_NULL (type)) {
1433 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1435 if (info.assembly.name)
1436 aname = mono_stringify_assembly_name (&info.assembly);
1437 else if (caller_assembly)
1438 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1440 aname = g_strdup ("");
1441 mono_error_set_type_load_name (error, tname, aname, "");
1443 mono_reflection_free_type_info (&info);
1449 if (!is_ok (error)) {
1451 mono_error_cleanup (error);
1452 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
1459 ICALL_EXPORT MonoReflectionTypeHandle
1460 ves_icall_System_Type_internal_from_handle (MonoType *handle, MonoError *error)
1462 mono_error_init (error);
1463 MonoDomain *domain = mono_domain_get ();
1465 return mono_type_get_object_handle (domain, handle, error);
1468 ICALL_EXPORT MonoType*
1469 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1471 return mono_class_get_type (klass);
1475 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1477 g_ptr_array_free (ptr_array, TRUE);
1481 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1487 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1490 char *res = mono_string_to_utf8_checked (s, &error);
1491 mono_error_set_pending_exception (&error);
1495 /* System.TypeCode */
1514 TYPECODE_STRING = 18
1517 ICALL_EXPORT guint32
1518 ves_icall_type_GetTypeCodeInternal (MonoReflectionTypeHandle ref_type, MonoError *error)
1520 mono_error_init (error);
1521 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1525 return TYPECODE_OBJECT;
1529 case MONO_TYPE_VOID:
1530 return TYPECODE_OBJECT;
1531 case MONO_TYPE_BOOLEAN:
1532 return TYPECODE_BOOLEAN;
1534 return TYPECODE_BYTE;
1536 return TYPECODE_SBYTE;
1538 return TYPECODE_UINT16;
1540 return TYPECODE_INT16;
1541 case MONO_TYPE_CHAR:
1542 return TYPECODE_CHAR;
1546 return TYPECODE_OBJECT;
1548 return TYPECODE_UINT32;
1550 return TYPECODE_INT32;
1552 return TYPECODE_UINT64;
1554 return TYPECODE_INT64;
1556 return TYPECODE_SINGLE;
1558 return TYPECODE_DOUBLE;
1559 case MONO_TYPE_VALUETYPE: {
1560 MonoClass *klass = type->data.klass;
1562 if (klass->enumtype) {
1563 t = mono_class_enum_basetype (klass)->type;
1565 } else if (mono_is_corlib_image (klass->image)) {
1566 if (strcmp (klass->name_space, "System") == 0) {
1567 if (strcmp (klass->name, "Decimal") == 0)
1568 return TYPECODE_DECIMAL;
1569 else if (strcmp (klass->name, "DateTime") == 0)
1570 return TYPECODE_DATETIME;
1573 return TYPECODE_OBJECT;
1575 case MONO_TYPE_STRING:
1576 return TYPECODE_STRING;
1577 case MONO_TYPE_SZARRAY:
1578 case MONO_TYPE_ARRAY:
1579 case MONO_TYPE_OBJECT:
1581 case MONO_TYPE_MVAR:
1582 case MONO_TYPE_TYPEDBYREF:
1583 return TYPECODE_OBJECT;
1584 case MONO_TYPE_CLASS:
1586 MonoClass *klass = type->data.klass;
1587 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1588 if (strcmp (klass->name, "DBNull") == 0)
1589 return TYPECODE_DBNULL;
1592 return TYPECODE_OBJECT;
1593 case MONO_TYPE_GENERICINST:
1594 return TYPECODE_OBJECT;
1596 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1602 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1604 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1605 return mono_class_enum_basetype (type->data.klass);
1606 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1607 return mono_class_enum_basetype (type->data.generic_class->container_class);
1611 ICALL_EXPORT guint32
1612 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_c, MonoError *error)
1614 mono_error_init (error);
1616 g_assert (!MONO_HANDLE_IS_NULL (ref_type));
1618 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1619 MonoClass *klass = mono_class_from_mono_type (type);
1620 MonoType *ctype = MONO_HANDLE_GETVAL (ref_c, type);
1621 MonoClass *klassc = mono_class_from_mono_type (ctype);
1623 if (type->byref ^ ctype->byref)
1627 MonoType *t = mono_type_get_underlying_type_ignore_byref (type);
1628 MonoType *ot = mono_type_get_underlying_type_ignore_byref (ctype);
1630 klass = mono_class_from_mono_type (t);
1631 klassc = mono_class_from_mono_type (ot);
1633 if (mono_type_is_primitive (t)) {
1634 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1635 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1636 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1637 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1638 return t->type == ot->type;
1640 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1643 if (klass->valuetype)
1644 return klass == klassc;
1645 return klass->valuetype == klassc->valuetype;
1648 return mono_class_is_assignable_from (klass, klassc);
1651 ICALL_EXPORT guint32
1652 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionTypeHandle ref_type, MonoObjectHandle obj, MonoError *error)
1654 mono_error_init (error);
1655 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1656 MonoClass *klass = mono_class_from_mono_type (type);
1657 mono_class_init_checked (klass, error);
1658 return_val_if_nok (error, FALSE);
1659 MonoObjectHandle inst = mono_object_handle_isinst (obj, klass, error);
1660 return_val_if_nok (error, FALSE);
1661 return !MONO_HANDLE_IS_NULL (inst);
1664 ICALL_EXPORT guint32
1665 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionTypeHandle ref_type, MonoError *error)
1667 mono_error_init (error);
1668 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1669 MonoClass *klass = mono_class_from_mono_type (type);
1670 return mono_class_get_flags (klass);
1673 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1674 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h, MonoError *error)
1676 mono_error_init (error);
1677 MonoDomain *domain = MONO_HANDLE_DOMAIN (field_h);
1678 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1679 MonoClass *klass = field->parent;
1681 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1682 if (mono_class_is_gtd (klass) ||
1683 (gklass && gklass->context.class_inst->is_open))
1684 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1686 MonoType *ftype = mono_field_get_type (field);
1687 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1688 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1690 MonoMarshalType *info = mono_marshal_load_type_info (klass);
1692 for (int i = 0; i < info->num_fields; ++i) {
1693 if (info->fields [i].field == field) {
1694 if (!info->fields [i].mspec)
1695 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1697 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain, klass, info->fields [i].mspec, error);
1702 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1705 ICALL_EXPORT MonoReflectionFieldHandle
1706 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type, MonoError *error)
1712 mono_error_init (error);
1715 klass = handle->parent;
1717 klass = mono_class_from_mono_type (type);
1719 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1722 /* The managed code will throw the exception */
1723 return MONO_HANDLE_CAST (MonoReflectionField, NULL_HANDLE);
1726 return mono_field_get_object_handle (mono_domain_get (), klass, handle, error);
1729 ICALL_EXPORT MonoReflectionEventHandle
1730 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type, MonoError *error)
1736 mono_error_init (error);
1739 klass = handle->parent;
1741 klass = mono_class_from_mono_type (type);
1743 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1745 /* Managed code will throw an exception */
1746 return MONO_HANDLE_CAST (MonoReflectionEvent, NULL_HANDLE);
1749 return mono_event_get_object_handle (mono_domain_get (), klass, handle, error);
1753 ICALL_EXPORT MonoReflectionPropertyHandle
1754 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type, MonoError *error)
1756 mono_error_init (error);
1762 klass = handle->parent;
1764 klass = mono_class_from_mono_type (type);
1766 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1768 /* Managed code will throw an exception */
1769 return MONO_HANDLE_CAST (MonoReflectionProperty, NULL_HANDLE);
1772 return mono_property_get_object_handle (mono_domain_get (), klass, handle, error);
1775 ICALL_EXPORT MonoArrayHandle
1776 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
1778 mono_error_init (error);
1779 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1781 MonoType *type = mono_field_get_type_checked (field, error);
1783 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1785 return type_array_from_modifiers (field->parent->image, type, optional, error);
1789 vell_icall_get_method_attributes (MonoMethod *method)
1791 return method->flags;
1795 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1798 MonoReflectionType *rt;
1799 MonoDomain *domain = mono_domain_get ();
1800 MonoMethodSignature* sig;
1802 sig = mono_method_signature_checked (method, &error);
1803 if (!mono_error_ok (&error)) {
1804 mono_error_set_pending_exception (&error);
1808 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1809 if (!mono_error_ok (&error)) {
1810 mono_error_set_pending_exception (&error);
1814 MONO_STRUCT_SETREF (info, parent, rt);
1816 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1817 if (!mono_error_ok (&error)) {
1818 mono_error_set_pending_exception (&error);
1822 MONO_STRUCT_SETREF (info, ret, rt);
1824 info->attrs = method->flags;
1825 info->implattrs = method->iflags;
1826 if (sig->call_convention == MONO_CALL_DEFAULT)
1827 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1829 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1834 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1837 ICALL_EXPORT MonoArrayHandle
1838 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod *method, MonoReflectionMethodHandle member, MonoError *error)
1840 mono_error_init (error);
1841 MonoDomain *domain = mono_domain_get ();
1843 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1844 MONO_HANDLE_GET (reftype, member, reftype);
1845 MonoClass *klass = NULL;
1846 if (!MONO_HANDLE_IS_NULL (reftype))
1847 klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype, type));
1848 return mono_param_get_objects_internal (domain, method, klass, error);
1851 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1852 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method, MonoError *error)
1854 mono_error_init (error);
1855 MonoDomain *domain = mono_domain_get ();
1856 MonoReflectionMarshalAsAttributeHandle res = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
1858 MonoMarshalSpec **mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1859 mono_method_get_marshal_info (method, mspecs);
1862 MONO_HANDLE_ASSIGN (res, mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], error));
1868 for (int i = mono_method_signature (method)->param_count; i >= 0; i--)
1870 mono_metadata_free_marshal_spec (mspecs [i]);
1877 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1879 MonoClass *parent = field->field->parent;
1880 mono_class_setup_fields (parent);
1882 return field->field->offset - sizeof (MonoObject);
1885 ICALL_EXPORT MonoReflectionTypeHandle
1886 ves_icall_MonoField_GetParentType (MonoReflectionFieldHandle field, MonoBoolean declaring, MonoError *error)
1888 mono_error_init (error);
1889 MonoDomain *domain = MONO_HANDLE_DOMAIN (field);
1893 MonoClassField *f = MONO_HANDLE_GETVAL (field, field);
1896 parent = MONO_HANDLE_GETVAL (field, klass);
1899 return mono_type_get_object_handle (domain, &parent->byval_arg, error);
1902 ICALL_EXPORT MonoObject *
1903 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1906 MonoClass *fklass = field->klass;
1907 MonoClassField *cf = field->field;
1908 MonoDomain *domain = mono_object_domain (field);
1910 if (fklass->image->assembly->ref_only) {
1911 mono_set_pending_exception (mono_get_exception_invalid_operation (
1912 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1916 if (mono_security_core_clr_enabled () &&
1917 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1918 mono_error_set_pending_exception (&error);
1922 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1923 mono_error_set_pending_exception (&error);
1928 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1931 MonoClassField *cf = field->field;
1935 if (field->klass->image->assembly->ref_only) {
1936 mono_set_pending_exception (mono_get_exception_invalid_operation (
1937 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1941 if (mono_security_core_clr_enabled () &&
1942 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1943 mono_error_set_pending_exception (&error);
1947 type = mono_field_get_type_checked (cf, &error);
1948 if (!mono_error_ok (&error)) {
1949 mono_error_set_pending_exception (&error);
1953 v = (gchar *) value;
1955 switch (type->type) {
1958 case MONO_TYPE_BOOLEAN:
1961 case MONO_TYPE_CHAR:
1970 case MONO_TYPE_VALUETYPE:
1973 v += sizeof (MonoObject);
1975 case MONO_TYPE_STRING:
1976 case MONO_TYPE_OBJECT:
1977 case MONO_TYPE_CLASS:
1978 case MONO_TYPE_ARRAY:
1979 case MONO_TYPE_SZARRAY:
1982 case MONO_TYPE_GENERICINST: {
1983 MonoGenericClass *gclass = type->data.generic_class;
1984 g_assert (!gclass->context.class_inst->is_open);
1986 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1987 MonoClass *nklass = mono_class_from_mono_type (type);
1988 MonoObject *nullable;
1991 * Convert the boxed vtype into a Nullable structure.
1992 * This is complicated by the fact that Nullables have
1993 * a variable structure.
1995 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
1996 if (!mono_error_ok (&error)) {
1997 mono_error_set_pending_exception (&error);
2001 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2003 v = (gchar *)mono_object_unbox (nullable);
2006 if (gclass->container_class->valuetype && (v != NULL))
2007 v += sizeof (MonoObject);
2011 g_error ("type 0x%x not handled in "
2012 "ves_icall_FieldInfo_SetValueInternal", type->type);
2017 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2018 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2019 if (!is_ok (&error)) {
2020 mono_error_set_pending_exception (&error);
2023 if (!vtable->initialized) {
2024 if (!mono_runtime_class_init_full (vtable, &error)) {
2025 mono_error_set_pending_exception (&error);
2029 mono_field_static_set_value (vtable, cf, v);
2031 mono_field_set_value (obj, cf, v);
2036 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2045 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2046 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2050 if (MONO_TYPE_IS_REFERENCE (f->type))
2051 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2053 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2056 ICALL_EXPORT MonoObject *
2057 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2059 MonoObject *o = NULL;
2060 MonoClassField *field = rfield->field;
2062 MonoDomain *domain = mono_object_domain (rfield);
2064 MonoTypeEnum def_type;
2065 const char *def_value;
2069 mono_class_init (field->parent);
2071 t = mono_field_get_type_checked (field, &error);
2072 if (!mono_error_ok (&error)) {
2073 mono_error_set_pending_exception (&error);
2077 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2078 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2082 if (image_is_dynamic (field->parent->image)) {
2083 MonoClass *klass = field->parent;
2084 int fidx = field - klass->fields;
2085 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2087 g_assert (def_values);
2088 def_type = def_values [fidx].def_type;
2089 def_value = def_values [fidx].data;
2091 if (def_type == MONO_TYPE_END) {
2092 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2096 def_value = mono_class_get_field_default_value (field, &def_type);
2097 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2099 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2104 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2108 case MONO_TYPE_BOOLEAN:
2111 case MONO_TYPE_CHAR:
2119 case MONO_TYPE_R8: {
2122 /* boxed value type */
2123 t = g_new0 (MonoType, 1);
2125 klass = mono_class_from_mono_type (t);
2127 o = mono_object_new_checked (domain, klass, &error);
2128 if (!mono_error_ok (&error)) {
2129 mono_error_set_pending_exception (&error);
2132 v = ((gchar *) o) + sizeof (MonoObject);
2133 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2134 if (mono_error_set_pending_exception (&error))
2138 case MONO_TYPE_STRING:
2139 case MONO_TYPE_CLASS:
2140 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2141 if (mono_error_set_pending_exception (&error))
2145 g_assert_not_reached ();
2151 ICALL_EXPORT MonoReflectionTypeHandle
2152 ves_icall_MonoField_ResolveType (MonoReflectionFieldHandle ref_field, MonoError *error)
2154 mono_error_init (error);
2155 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_field);
2156 MonoClassField *field = MONO_HANDLE_GETVAL (ref_field, field);
2157 MonoType *type = mono_field_get_type_checked (field, error);
2158 if (!is_ok (error)) {
2159 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2161 return mono_type_get_object_handle (domain, type, error);
2164 /* From MonoProperty.cs */
2166 PInfo_Attributes = 1,
2167 PInfo_GetMethod = 1 << 1,
2168 PInfo_SetMethod = 1 << 2,
2169 PInfo_ReflectedType = 1 << 3,
2170 PInfo_DeclaringType = 1 << 4,
2175 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2178 MonoReflectionType *rt;
2179 MonoReflectionMethod *rm;
2180 MonoDomain *domain = mono_object_domain (property);
2181 const MonoProperty *pproperty = property->property;
2183 if ((req_info & PInfo_ReflectedType) != 0) {
2184 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2185 if (mono_error_set_pending_exception (&error))
2188 MONO_STRUCT_SETREF (info, parent, rt);
2190 if ((req_info & PInfo_DeclaringType) != 0) {
2191 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2192 if (mono_error_set_pending_exception (&error))
2195 MONO_STRUCT_SETREF (info, declaring_type, rt);
2198 if ((req_info & PInfo_Name) != 0)
2199 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2201 if ((req_info & PInfo_Attributes) != 0)
2202 info->attrs = pproperty->attrs;
2204 if ((req_info & PInfo_GetMethod) != 0) {
2205 if (pproperty->get &&
2206 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2207 pproperty->get->klass == property->klass)) {
2208 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2209 if (mono_error_set_pending_exception (&error))
2215 MONO_STRUCT_SETREF (info, get, rm);
2217 if ((req_info & PInfo_SetMethod) != 0) {
2218 if (pproperty->set &&
2219 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2220 pproperty->set->klass == property->klass)) {
2221 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2222 if (mono_error_set_pending_exception (&error))
2228 MONO_STRUCT_SETREF (info, set, rm);
2231 * There may be other methods defined for properties, though, it seems they are not exposed
2232 * in the reflection API
2237 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2240 MonoReflectionType *rt;
2241 MonoReflectionMethod *rm;
2242 MonoDomain *domain = mono_object_domain (event);
2244 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2245 if (mono_error_set_pending_exception (&error))
2248 MONO_STRUCT_SETREF (info, reflected_type, rt);
2250 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2251 if (mono_error_set_pending_exception (&error))
2254 MONO_STRUCT_SETREF (info, declaring_type, rt);
2256 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2257 info->attrs = event->event->attrs;
2259 if (event->event->add) {
2260 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2261 if (mono_error_set_pending_exception (&error))
2267 MONO_STRUCT_SETREF (info, add_method, rm);
2269 if (event->event->remove) {
2270 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2271 if (mono_error_set_pending_exception (&error))
2277 MONO_STRUCT_SETREF (info, remove_method, rm);
2279 if (event->event->raise) {
2280 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2281 if (mono_error_set_pending_exception (&error))
2287 MONO_STRUCT_SETREF (info, raise_method, rm);
2289 #ifndef MONO_SMALL_CONFIG
2290 if (event->event->other) {
2292 while (event->event->other [n])
2294 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2295 if (mono_error_set_pending_exception (&error))
2297 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2299 for (i = 0; i < n; i++) {
2300 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2301 if (mono_error_set_pending_exception (&error))
2303 mono_array_setref (info->other_methods, i, rm);
2310 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2315 mono_class_setup_interfaces (klass, error);
2316 if (!mono_error_ok (error))
2319 for (i = 0; i < klass->interface_count; i++) {
2320 ic = klass->interfaces [i];
2321 g_hash_table_insert (ifaces, ic, ic);
2323 collect_interfaces (ic, ifaces, error);
2324 if (!mono_error_ok (error))
2330 MonoArrayHandle iface_array;
2331 MonoGenericContext *context;
2335 } FillIfaceArrayData;
2338 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2340 HANDLE_FUNCTION_ENTER ();
2341 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2342 MonoClass *ic = (MonoClass *)key;
2343 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2344 MonoError *error = data->error;
2349 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2350 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, error);
2355 MonoReflectionTypeHandle rt = mono_type_get_object_handle (data->domain, ret, error);
2359 MONO_HANDLE_ARRAY_SETREF (data->iface_array, data->next_idx, rt);
2363 mono_metadata_free_type (inflated);
2365 HANDLE_FUNCTION_RETURN ();
2369 get_interfaces_hash (gconstpointer v1)
2371 MonoClass *k = (MonoClass*)v1;
2373 return k->type_token;
2376 ICALL_EXPORT MonoArrayHandle
2377 ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type, MonoError *error)
2379 mono_error_init (error);
2380 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2381 MonoClass *klass = mono_class_from_mono_type (type);
2383 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2385 MonoGenericContext *context = NULL;
2386 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2387 context = mono_class_get_context (klass);
2388 klass = mono_class_get_generic_class (klass)->container_class;
2391 for (MonoClass *parent = klass; parent; parent = parent->parent) {
2392 mono_class_setup_interfaces (parent, error);
2395 collect_interfaces (parent, iface_hash, error);
2400 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2402 int len = g_hash_table_size (iface_hash);
2404 g_hash_table_destroy (iface_hash);
2405 if (!domain->empty_types) {
2406 domain->empty_types = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, error);
2410 return MONO_HANDLE_NEW (MonoArray, domain->empty_types);
2413 FillIfaceArrayData data;
2414 data.iface_array = MONO_HANDLE_NEW (MonoArray, mono_array_new_cached (domain, mono_defaults.runtimetype_class, len, error));
2417 data.context = context;
2419 data.domain = domain;
2422 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2427 g_hash_table_destroy (iface_hash);
2428 return data.iface_array;
2431 g_hash_table_destroy (iface_hash);
2432 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
2436 set_interface_map_data_method_object (MonoDomain *domain, MonoMethod *method, MonoClass *iclass, int ioffset, MonoClass *klass, MonoArrayHandle targets, MonoArrayHandle methods, int i, MonoError *error)
2438 HANDLE_FUNCTION_ENTER ();
2439 mono_error_init (error);
2440 MonoReflectionMethodHandle member = mono_method_get_object_handle (domain, method, iclass, error);
2444 MONO_HANDLE_ARRAY_SETREF (methods, i, member);
2446 MONO_HANDLE_ASSIGN (member, mono_method_get_object_handle (domain, klass->vtable [i + ioffset], klass, error));
2450 MONO_HANDLE_ARRAY_SETREF (targets, i, member);
2453 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2457 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_iface, MonoArrayHandleOut targets, MonoArrayHandleOut methods, MonoError *error)
2459 mono_error_init (error);
2460 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2461 MonoClass *klass = mono_class_from_mono_type (type);
2462 MonoType *iface = MONO_HANDLE_GETVAL (ref_iface, type);
2463 MonoClass *iclass = mono_class_from_mono_type (iface);
2465 mono_class_init_checked (klass, error);
2466 return_if_nok (error);
2467 mono_class_init_checked (iclass, error);
2468 return_if_nok (error);
2470 mono_class_setup_vtable (klass);
2472 gboolean variance_used;
2473 int ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2477 int len = mono_class_num_methods (iclass);
2478 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2479 MonoArrayHandle targets_arr = mono_array_new_handle (domain, mono_defaults.method_info_class, len, error);
2480 return_if_nok (error);
2481 MONO_HANDLE_ASSIGN (targets, targets_arr);
2483 MonoArrayHandle methods_arr = mono_array_new_handle (domain, mono_defaults.method_info_class, len, error);
2484 return_if_nok (error);
2485 MONO_HANDLE_ASSIGN (methods, methods_arr);
2489 gpointer iter = NULL;
2490 while ((method = mono_class_get_methods (iclass, &iter))) {
2491 if (!set_interface_map_data_method_object (domain, method, iclass, ioffset, klass, targets, methods, i, error))
2498 ves_icall_RuntimeType_GetPacking (MonoReflectionTypeHandle ref_type, guint32 *packing, guint32 *size, MonoError *error)
2500 mono_error_init (error);
2501 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2502 MonoClass *klass = mono_class_from_mono_type (type);
2504 mono_class_init_checked (klass, error);
2508 if (image_is_dynamic (klass->image)) {
2509 MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_type);
2510 *packing = MONO_HANDLE_GETVAL (tb, packing_size);
2511 *size = MONO_HANDLE_GETVAL (tb, class_size);
2513 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2517 ICALL_EXPORT MonoReflectionTypeHandle
2518 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionTypeHandle ref_type, MonoError *error)
2520 mono_error_init (error);
2522 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2523 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2525 if (!type->byref && type->type == MONO_TYPE_SZARRAY) {
2526 return mono_type_get_object_handle (domain, &type->data.klass->byval_arg, error);
2529 MonoClass *klass = mono_class_from_mono_type (type);
2530 mono_class_init_checked (klass, error);
2532 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2534 // GetElementType should only return a type for:
2535 // Array Pointer PassedByRef
2537 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2538 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2539 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2540 else if (klass->element_class && type->type == MONO_TYPE_PTR)
2541 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2543 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2546 ICALL_EXPORT MonoReflectionTypeHandle
2547 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionTypeHandle ref_type, MonoError *error)
2549 mono_error_init (error);
2551 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2552 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2555 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2557 MonoClass *klass = mono_class_from_mono_type (type);
2559 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2561 return mono_type_get_object_handle (domain, &klass->parent->byval_arg, error);
2564 ICALL_EXPORT MonoBoolean
2565 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionTypeHandle ref_type, MonoError *error)
2567 mono_error_init (error);
2568 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2569 return type->type == MONO_TYPE_PTR;
2572 ICALL_EXPORT MonoBoolean
2573 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type, MonoError *error)
2575 mono_error_init (error);
2576 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2577 return (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)));
2580 ICALL_EXPORT MonoBoolean
2581 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type, MonoError *error)
2583 mono_error_init (error);
2584 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2588 ICALL_EXPORT MonoBoolean
2589 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionTypeHandle ref_type, MonoError *error)
2591 mono_error_init (error);
2592 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2593 MonoClass *klass = mono_class_from_mono_type (type);
2594 mono_class_init_checked (klass, error);
2598 return mono_class_is_com_object (klass);
2601 ICALL_EXPORT guint32
2602 ves_icall_reflection_get_token (MonoObjectHandle obj, MonoError *error)
2604 mono_error_init (error);
2605 return mono_reflection_get_token_checked (obj, error);
2608 ICALL_EXPORT MonoReflectionModuleHandle
2609 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2611 mono_error_init (error);
2612 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2613 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2614 MonoClass *klass = mono_class_from_mono_type (t);
2615 return mono_module_get_object_handle (domain, klass->image, error);
2618 ICALL_EXPORT MonoReflectionAssemblyHandle
2619 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2621 mono_error_init (error);
2622 MonoDomain *domain = mono_domain_get ();
2623 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2624 MonoClass *klass = mono_class_from_mono_type (t);
2625 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2628 ICALL_EXPORT MonoReflectionTypeHandle
2629 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionTypeHandle ref_type, MonoError *error)
2631 mono_error_init (error);
2632 MonoDomain *domain = mono_domain_get ();
2633 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2637 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2638 if (type->type == MONO_TYPE_VAR) {
2639 MonoGenericContainer *param = mono_type_get_generic_param_owner (type);
2640 klass = param ? param->owner.klass : NULL;
2641 } else if (type->type == MONO_TYPE_MVAR) {
2642 MonoGenericContainer *param = mono_type_get_generic_param_owner (type);
2643 klass = param ? param->owner.method->klass : NULL;
2645 klass = mono_class_from_mono_type (type)->nested_in;
2649 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2651 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2654 ICALL_EXPORT MonoStringHandle
2655 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2657 MonoDomain *domain = mono_domain_get ();
2658 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2659 MonoClass *klass = mono_class_from_mono_type (type);
2662 char *n = g_strdup_printf ("%s&", klass->name);
2663 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2669 return mono_string_new_handle (domain, klass->name, error);
2673 ICALL_EXPORT MonoStringHandle
2674 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2676 MonoDomain *domain = mono_domain_get ();
2677 MonoClass *klass = mono_class_from_mono_type_handle (type);
2679 while (klass->nested_in)
2680 klass = klass->nested_in;
2682 if (klass->name_space [0] == '\0')
2683 return NULL_HANDLE_STRING;
2685 return mono_string_new_handle (domain, klass->name_space, error);
2689 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionTypeHandle ref_type, MonoError *error)
2691 mono_error_init (error);
2692 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2694 if (type->type != MONO_TYPE_ARRAY && type->type != MONO_TYPE_SZARRAY) {
2695 mono_error_set_argument (error, "type", "Type must be an array type");
2699 MonoClass *klass = mono_class_from_mono_type (type);
2704 static MonoArrayHandle
2705 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2707 return mono_array_new_handle (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2711 set_type_object_in_array (MonoDomain *domain, MonoType *type, MonoArrayHandle dest, int i, MonoError *error)
2713 HANDLE_FUNCTION_ENTER();
2714 mono_error_init (error);
2715 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, type, error);
2719 MONO_HANDLE_ARRAY_SETREF (dest, i, rt);
2722 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2725 ICALL_EXPORT MonoArrayHandle
2726 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionTypeHandle ref_type, MonoBoolean runtimeTypeArray, MonoError *error)
2728 mono_error_init (error);
2729 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2731 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2732 MonoClass *klass = mono_class_from_mono_type (type);
2734 MonoArrayHandle res = MONO_HANDLE_NEW (MonoArray, NULL);
2735 if (mono_class_is_gtd (klass)) {
2736 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2737 MONO_HANDLE_ASSIGN (res, create_type_array (domain, runtimeTypeArray, container->type_argc, error));
2740 for (int i = 0; i < container->type_argc; ++i) {
2741 MonoClass *pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2743 if (!set_type_object_in_array (domain, &pklass->byval_arg, res, i, error))
2747 } else if (mono_class_is_ginst (klass)) {
2748 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2749 MONO_HANDLE_ASSIGN (res, create_type_array (domain, runtimeTypeArray, inst->type_argc, error));
2752 for (int i = 0; i < inst->type_argc; ++i) {
2753 if (!set_type_object_in_array (domain, inst->type_argv [i], res, i, error))
2762 ICALL_EXPORT gboolean
2763 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionTypeHandle ref_type, MonoError *error)
2765 mono_error_init (error);
2767 if (!IS_MONOTYPE (MONO_HANDLE_RAW(ref_type)))
2770 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2774 MonoClass *klass = mono_class_from_mono_type (type);
2775 return mono_class_is_gtd (klass);
2778 ICALL_EXPORT MonoReflectionTypeHandle
2779 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionTypeHandle ref_type, MonoError *error)
2781 mono_error_init (error);
2782 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2784 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW (MonoReflectionType, NULL);
2789 MonoClass *klass = mono_class_from_mono_type (type);
2791 if (mono_class_is_gtd (klass)) {
2792 /* check this one */
2793 MONO_HANDLE_ASSIGN (ret, ref_type);
2796 if (mono_class_is_ginst (klass)) {
2797 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2799 guint32 ref_info_handle = mono_class_get_ref_info_handle (generic_class);
2801 if (generic_class->wastypebuilder && ref_info_handle) {
2802 MonoObjectHandle tb = mono_gchandle_get_target_handle (ref_info_handle);
2803 g_assert (!MONO_HANDLE_IS_NULL (tb));
2804 MONO_HANDLE_ASSIGN (ret, tb);
2806 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2807 MONO_HANDLE_ASSIGN (ret, mono_type_get_object_handle (domain, &generic_class->byval_arg, error));
2814 ICALL_EXPORT MonoReflectionTypeHandle
2815 ves_icall_RuntimeType_MakeGenericType (MonoReflectionTypeHandle reftype, MonoArrayHandle type_array, MonoError *error)
2817 mono_error_init (error);
2818 MonoDomain *domain = MONO_HANDLE_DOMAIN (reftype);
2820 g_assert (IS_MONOTYPE_HANDLE (reftype));
2821 MonoType *type = MONO_HANDLE_GETVAL (reftype, type);
2822 mono_class_init_checked (mono_class_from_mono_type (type), error);
2824 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2826 int count = mono_array_handle_length (type_array);
2827 MonoType **types = g_new0 (MonoType *, count);
2829 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
2830 for (int i = 0; i < count; i++) {
2831 MONO_HANDLE_ARRAY_GETREF (t, type_array, i);
2832 types [i] = MONO_HANDLE_GETVAL (t, type);
2835 MonoType *geninst = mono_reflection_bind_generic_parameters (reftype, count, types, error);
2838 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2841 MonoClass *klass = mono_class_from_mono_type (geninst);
2843 /*we might inflate to the GTD*/
2844 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2845 mono_error_set_argument (error, "typeArguments", "Invalid generic arguments");
2846 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2849 return mono_type_get_object_handle (domain, geninst, error);
2852 ICALL_EXPORT gboolean
2853 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionTypeHandle ref_type, MonoError *error)
2855 mono_error_init (error);
2858 if (!IS_MONOTYPE (MONO_HANDLE_RAW (ref_type)))
2861 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2865 klass = mono_class_from_mono_type (type);
2866 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2870 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionTypeHandle ref_type, MonoError *error)
2872 mono_error_init (error);
2873 if (!IS_MONOTYPE_HANDLE (ref_type))
2875 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2877 if (is_generic_parameter (type))
2878 return mono_type_get_generic_param_num (type);
2882 ICALL_EXPORT MonoGenericParamInfo *
2883 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionTypeHandle ref_type, MonoError *error)
2885 mono_error_init (error);
2886 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2887 return mono_generic_param_info (type->data.generic_param);
2890 ICALL_EXPORT MonoBoolean
2891 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionTypeHandle ref_type, MonoError *error)
2893 MonoType *type = MONO_HANDLE_GETVAL(ref_type, type);
2894 return is_generic_parameter (type);
2897 ICALL_EXPORT MonoReflectionMethodHandle
2898 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionTypeHandle ref_type,
2899 MonoReflectionMethodHandle generic,
2902 mono_error_init (error);
2903 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2904 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2905 MonoClass *klass = mono_class_from_mono_type (type);
2907 mono_class_init_checked (klass, error);
2909 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2911 MonoMethod *generic_method = MONO_HANDLE_GETVAL (generic, method);
2913 MonoReflectionMethodHandle ret = MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2915 gpointer iter = NULL;
2916 while ((method = mono_class_get_methods (klass, &iter))) {
2917 if (method->token == generic_method->token) {
2918 ret = mono_method_get_object_handle (domain, method, klass, error);
2920 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2927 ICALL_EXPORT MonoReflectionMethodHandle
2928 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionTypeHandle ref_type, MonoError *error)
2930 mono_error_init (error);
2931 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2932 MonoReflectionMethodHandle ret = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
2934 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2935 mono_error_set_invalid_operation (error, "DeclaringMethod can only be used on generic arguments");
2938 if (type->type == MONO_TYPE_VAR)
2941 MonoMethod *method = mono_type_get_generic_param_owner (type)->owner.method;
2944 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2946 MONO_HANDLE_ASSIGN (ret, mono_method_get_object_handle (domain, method, method->klass, error));
2951 ICALL_EXPORT MonoBoolean
2952 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (MonoError *error)
2954 mono_error_init (error);
2955 mono_error_set_not_implemented (error, "%s", "");
2959 ICALL_EXPORT MonoBoolean
2960 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (MonoError *error)
2962 mono_error_init (error);
2963 mono_error_set_not_implemented (error, "%s", "");
2968 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2970 MonoDomain *domain = mono_domain_get ();
2971 MonoImage *image = method->method->klass->image;
2972 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2973 MonoTableInfo *tables = image->tables;
2974 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2975 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2976 guint32 im_cols [MONO_IMPLMAP_SIZE];
2977 guint32 scope_token;
2978 const char *import = NULL;
2979 const char *scope = NULL;
2981 if (image_is_dynamic (image)) {
2982 MonoReflectionMethodAux *method_aux =
2983 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2985 import = method_aux->dllentry;
2986 scope = method_aux->dll;
2989 if (!import || !scope) {
2990 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2995 if (piinfo->implmap_idx) {
2996 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2998 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2999 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
3000 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
3001 scope = mono_metadata_string_heap (image, scope_token);
3005 *flags = piinfo->piflags;
3006 *entry_point = mono_string_new (domain, import);
3007 *dll_name = mono_string_new (domain, scope);
3010 ICALL_EXPORT MonoReflectionMethod *
3011 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3013 MonoMethodInflated *imethod;
3015 MonoReflectionMethod *ret = NULL;
3018 if (method->method->is_generic)
3021 if (!method->method->is_inflated)
3024 imethod = (MonoMethodInflated *) method->method;
3026 result = imethod->declaring;
3027 /* Not a generic method. */
3028 if (!result->is_generic)
3031 if (image_is_dynamic (method->method->klass->image)) {
3032 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3033 MonoReflectionMethod *res;
3036 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3037 * the dynamic case as well ?
3039 mono_image_lock ((MonoImage*)image);
3040 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3041 mono_image_unlock ((MonoImage*)image);
3047 if (imethod->context.class_inst) {
3048 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3049 /*Generic methods gets the context of the GTD.*/
3050 if (mono_class_get_context (klass)) {
3051 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3052 if (!mono_error_ok (&error))
3057 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3059 if (!mono_error_ok (&error))
3060 mono_error_set_pending_exception (&error);
3064 ICALL_EXPORT gboolean
3065 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3067 return mono_method_signature (method->method)->generic_param_count != 0;
3070 ICALL_EXPORT gboolean
3071 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3073 return method->method->is_generic;
3076 ICALL_EXPORT MonoArray*
3077 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3080 MonoReflectionType *rt;
3085 domain = mono_object_domain (method);
3087 if (method->method->is_inflated) {
3088 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3091 count = inst->type_argc;
3092 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3093 if (mono_error_set_pending_exception (&error))
3096 for (i = 0; i < count; i++) {
3097 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3098 if (mono_error_set_pending_exception (&error))
3101 mono_array_setref (res, i, rt);
3108 count = mono_method_signature (method->method)->generic_param_count;
3109 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3110 if (mono_error_set_pending_exception (&error))
3113 for (i = 0; i < count; i++) {
3114 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3115 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3116 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3118 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3119 if (mono_error_set_pending_exception (&error))
3122 mono_array_setref (res, i, rt);
3128 ICALL_EXPORT MonoObject *
3129 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3133 * Invoke from reflection is supposed to always be a virtual call (the API
3134 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3135 * greater flexibility.
3137 MonoMethod *m = method->method;
3138 MonoMethodSignature *sig = mono_method_signature (m);
3141 void *obj = this_arg;
3145 if (mono_security_core_clr_enabled () &&
3146 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3147 mono_error_set_pending_exception (&error);
3151 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3152 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3153 mono_error_cleanup (&error); /* FIXME does this make sense? */
3154 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3159 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3160 if (!is_ok (&error)) {
3161 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3164 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3165 char *target_name = mono_type_get_full_name (m->klass);
3166 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3167 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3169 g_free (target_name);
3173 m = mono_object_get_virtual_method (this_arg, m);
3174 /* must pass the pointer to the value for valuetype methods */
3175 if (m->klass->valuetype)
3176 obj = mono_object_unbox (this_arg);
3177 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3178 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3183 if (sig->ret->byref) {
3184 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"));
3188 pcount = params? mono_array_length (params): 0;
3189 if (pcount != sig->param_count) {
3190 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3194 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3195 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."));
3199 image = m->klass->image;
3200 if (image->assembly->ref_only) {
3201 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."));
3205 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3206 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3210 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3214 intptr_t *lower_bounds;
3215 pcount = mono_array_length (params);
3216 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3217 /* Note: the synthetized array .ctors have int32 as argument type */
3218 for (i = 0; i < pcount; ++i)
3219 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3221 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3222 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3223 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3224 if (!mono_error_ok (&error)) {
3225 mono_error_set_pending_exception (&error);
3229 for (i = 0; i < mono_array_length (arr); ++i) {
3230 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3231 if (!mono_error_ok (&error)) {
3232 mono_error_set_pending_exception (&error);
3235 mono_array_setref_fast (arr, i, subarray);
3237 return (MonoObject*)arr;
3240 if (m->klass->rank == pcount) {
3241 /* Only lengths provided. */
3242 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3243 if (!mono_error_ok (&error)) {
3244 mono_error_set_pending_exception (&error);
3248 return (MonoObject*)arr;
3250 g_assert (pcount == (m->klass->rank * 2));
3251 /* The arguments are lower-bound-length pairs */
3252 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3254 for (i = 0; i < pcount / 2; ++i) {
3255 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3256 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3259 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3260 if (!mono_error_ok (&error)) {
3261 mono_error_set_pending_exception (&error);
3265 return (MonoObject*)arr;
3268 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3269 mono_error_set_pending_exception (&error);
3273 #ifndef DISABLE_REMOTING
3274 ICALL_EXPORT MonoObject *
3275 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3278 MonoDomain *domain = mono_object_domain (method);
3279 MonoMethod *m = method->method;
3280 MonoMethodSignature *sig = mono_method_signature (m);
3281 MonoArray *out_args;
3283 int i, j, outarg_count = 0;
3285 if (m->klass == mono_defaults.object_class) {
3286 if (!strcmp (m->name, "FieldGetter")) {
3287 MonoClass *k = mono_object_class (this_arg);
3291 /* If this is a proxy, then it must be a CBO */
3292 if (mono_class_is_transparent_proxy (k)) {
3293 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3294 this_arg = tp->rp->unwrapped_server;
3295 g_assert (this_arg);
3296 k = mono_object_class (this_arg);
3299 name = mono_array_get (params, MonoString *, 1);
3300 str = mono_string_to_utf8_checked (name, &error);
3301 if (mono_error_set_pending_exception (&error))
3305 MonoClassField* field = mono_class_get_field_from_name (k, str);
3308 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3309 if (field_klass->valuetype) {
3310 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3311 if (mono_error_set_pending_exception (&error))
3314 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3316 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3317 if (mono_error_set_pending_exception (&error))
3319 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3320 mono_array_setref (out_args, 0, result);
3327 g_assert_not_reached ();
3329 } else if (!strcmp (m->name, "FieldSetter")) {
3330 MonoClass *k = mono_object_class (this_arg);
3336 /* If this is a proxy, then it must be a CBO */
3337 if (mono_class_is_transparent_proxy (k)) {
3338 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3339 this_arg = tp->rp->unwrapped_server;
3340 g_assert (this_arg);
3341 k = mono_object_class (this_arg);
3344 name = mono_array_get (params, MonoString *, 1);
3345 str = mono_string_to_utf8_checked (name, &error);
3346 if (mono_error_set_pending_exception (&error))
3350 MonoClassField* field = mono_class_get_field_from_name (k, str);
3353 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3354 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3356 if (field_klass->valuetype) {
3357 size = mono_type_size (field->type, &align);
3358 g_assert (size == mono_class_value_size (field_klass, NULL));
3359 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3361 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3364 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3365 if (mono_error_set_pending_exception (&error))
3367 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3376 g_assert_not_reached ();
3381 for (i = 0; i < mono_array_length (params); i++) {
3382 if (sig->params [i]->byref)
3386 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3387 if (mono_error_set_pending_exception (&error))
3390 /* handle constructors only for objects already allocated */
3391 if (!strcmp (method->method->name, ".ctor"))
3392 g_assert (this_arg);
3394 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3395 g_assert (!method->method->klass->valuetype);
3396 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3397 if (mono_error_set_pending_exception (&error))
3400 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3401 if (sig->params [i]->byref) {
3403 arg = mono_array_get (params, gpointer, i);
3404 mono_array_setref (out_args, j, arg);
3409 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3416 read_enum_value (const char *mem, int type)
3419 case MONO_TYPE_BOOLEAN:
3421 return *(guint8*)mem;
3423 return *(gint8*)mem;
3424 case MONO_TYPE_CHAR:
3426 return read16 (mem);
3428 return (gint16) read16 (mem);
3430 return read32 (mem);
3432 return (gint32) read32 (mem);
3435 return read64 (mem);
3437 g_assert_not_reached ();
3443 write_enum_value (char *mem, int type, guint64 value)
3447 case MONO_TYPE_I1: {
3448 guint8 *p = (guint8*)mem;
3454 case MONO_TYPE_CHAR: {
3455 guint16 *p = (guint16 *)mem;
3460 case MONO_TYPE_I4: {
3461 guint32 *p = (guint32 *)mem;
3466 case MONO_TYPE_I8: {
3467 guint64 *p = (guint64 *)mem;
3472 g_assert_not_reached ();
3477 ICALL_EXPORT MonoObject *
3478 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3486 domain = mono_object_domain (enumType);
3487 enumc = mono_class_from_mono_type (enumType->type);
3489 mono_class_init_checked (enumc, &error);
3490 if (mono_error_set_pending_exception (&error))
3493 etype = mono_class_enum_basetype (enumc);
3495 res = mono_object_new_checked (domain, enumc, &error);
3496 if (mono_error_set_pending_exception (&error))
3498 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3503 ICALL_EXPORT MonoBoolean
3504 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3506 int size = mono_class_value_size (a->vtable->klass, NULL);
3507 guint64 a_val = 0, b_val = 0;
3509 memcpy (&a_val, mono_object_unbox (a), size);
3510 memcpy (&b_val, mono_object_unbox (b), size);
3512 return (a_val & b_val) == b_val;
3515 ICALL_EXPORT MonoObject *
3516 ves_icall_System_Enum_get_value (MonoObject *eobj)
3528 g_assert (eobj->vtable->klass->enumtype);
3530 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3531 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3532 if (mono_error_set_pending_exception (&error))
3534 dst = (char *)res + sizeof (MonoObject);
3535 src = (char *)eobj + sizeof (MonoObject);
3536 size = mono_class_value_size (enumc, NULL);
3538 memcpy (dst, src, size);
3543 ICALL_EXPORT MonoReflectionType *
3544 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3547 MonoReflectionType *ret;
3551 klass = mono_class_from_mono_type (type->type);
3552 mono_class_init_checked (klass, &error);
3553 if (mono_error_set_pending_exception (&error))
3556 etype = mono_class_enum_basetype (klass);
3558 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3562 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3563 mono_error_set_pending_exception (&error);
3569 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3571 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3572 gpointer odata = (char *)other + sizeof (MonoObject);
3573 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3574 g_assert (basetype);
3579 if (eobj->vtable->klass != other->vtable->klass)
3582 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3583 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3584 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3587 return me > other ? 1 : -1; \
3590 switch (basetype->type) {
3592 COMPARE_ENUM_VALUES (guint8);
3594 COMPARE_ENUM_VALUES (gint8);
3595 case MONO_TYPE_CHAR:
3597 COMPARE_ENUM_VALUES (guint16);
3599 COMPARE_ENUM_VALUES (gint16);
3601 COMPARE_ENUM_VALUES (guint32);
3603 COMPARE_ENUM_VALUES (gint32);
3605 COMPARE_ENUM_VALUES (guint64);
3607 COMPARE_ENUM_VALUES (gint64);
3611 #undef COMPARE_ENUM_VALUES
3612 /* indicates that the enum was of an unsupported unerlying type */
3617 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3619 gpointer data = (char *)eobj + sizeof (MonoObject);
3620 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3621 g_assert (basetype);
3623 switch (basetype->type) {
3624 case MONO_TYPE_I1: {
3625 gint8 value = *((gint8*)data);
3626 return ((int)value ^ (int)value << 8);
3629 return *((guint8*)data);
3630 case MONO_TYPE_CHAR:
3632 return *((guint16*)data);
3634 case MONO_TYPE_I2: {
3635 gint16 value = *((gint16*)data);
3636 return ((int)(guint16)value | (((int)value) << 16));
3639 return *((guint32*)data);
3641 return *((gint32*)data);
3643 case MONO_TYPE_I8: {
3644 gint64 value = *((gint64*)data);
3645 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3648 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3654 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3656 mono_error_init (error);
3657 HANDLE_FUNCTION_ENTER();
3658 guint64 field_value;
3660 MonoTypeEnum def_type;
3662 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3664 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3666 if (mono_field_is_deleted (field))
3668 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3671 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3673 p = mono_class_get_field_default_value (field, &def_type);
3674 /* len = */ mono_metadata_decode_blob_size (p, &p);
3676 field_value = read_enum_value (p, base_type);
3677 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3679 if (*previous_value > field_value)
3682 *previous_value = field_value;
3685 HANDLE_FUNCTION_RETURN();
3688 ICALL_EXPORT MonoBoolean
3689 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3691 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3692 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3693 guint j = 0, nvalues;
3695 MonoClassField *field;
3697 guint64 previous_value = 0;
3698 gboolean sorted = TRUE;
3700 mono_error_init (error);
3701 mono_class_init_checked (enumc, error);
3702 return_val_if_nok (error, FALSE);
3704 if (!enumc->enumtype) {
3705 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3709 base_type = mono_class_enum_basetype (enumc)->type;
3711 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3712 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3713 return_val_if_nok (error, FALSE);
3714 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3715 return_val_if_nok (error, FALSE);
3718 while ((field = mono_class_get_fields (enumc, &iter))) {
3719 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3723 return_val_if_nok (error, FALSE);
3729 BFLAGS_IgnoreCase = 1,
3730 BFLAGS_DeclaredOnly = 2,
3731 BFLAGS_Instance = 4,
3733 BFLAGS_Public = 0x10,
3734 BFLAGS_NonPublic = 0x20,
3735 BFLAGS_FlattenHierarchy = 0x40,
3736 BFLAGS_InvokeMethod = 0x100,
3737 BFLAGS_CreateInstance = 0x200,
3738 BFLAGS_GetField = 0x400,
3739 BFLAGS_SetField = 0x800,
3740 BFLAGS_GetProperty = 0x1000,
3741 BFLAGS_SetProperty = 0x2000,
3742 BFLAGS_ExactBinding = 0x10000,
3743 BFLAGS_SuppressChangeType = 0x20000,
3744 BFLAGS_OptionalParamBinding = 0x40000
3747 ICALL_EXPORT GPtrArray*
3748 ves_icall_RuntimeType_GetFields_native (MonoReflectionTypeHandle ref_type, char *utf8_name, guint32 bflags, MonoError *error)
3750 mono_error_init (error);
3751 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3754 return g_ptr_array_new ();
3757 int (*compare_func) (const char *s1, const char *s2) = NULL;
3758 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3760 MonoClass *startklass, *klass;
3761 klass = startklass = mono_class_from_mono_type (type);
3763 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3766 if (mono_class_has_failure (klass)) {
3767 mono_error_set_for_class_failure (error, klass);
3771 MonoClassField *field;
3772 gpointer iter = NULL;
3773 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3774 guint32 flags = mono_field_get_flags (field);
3776 if (mono_field_is_deleted_with_flags (field, flags))
3778 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3779 if (bflags & BFLAGS_Public)
3781 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3782 if (bflags & BFLAGS_NonPublic) {
3789 if (flags & FIELD_ATTRIBUTE_STATIC) {
3790 if (bflags & BFLAGS_Static)
3791 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3794 if (bflags & BFLAGS_Instance)
3801 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3804 g_ptr_array_add (ptr_array, field);
3806 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3812 g_ptr_array_free (ptr_array, TRUE);
3817 method_nonpublic (MonoMethod* method, gboolean start_klass)
3819 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3820 case METHOD_ATTRIBUTE_ASSEM:
3821 return (start_klass || mono_defaults.generic_ilist_class);
3822 case METHOD_ATTRIBUTE_PRIVATE:
3824 case METHOD_ATTRIBUTE_PUBLIC:
3832 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3835 MonoClass *startklass;
3839 /*FIXME, use MonoBitSet*/
3840 guint32 method_slots_default [8];
3841 guint32 *method_slots = NULL;
3842 int (*compare_func) (const char *s1, const char *s2) = NULL;
3844 array = g_ptr_array_new ();
3846 mono_error_init (error);
3849 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3851 /* An optimization for calls made from Delegate:CreateDelegate () */
3852 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3853 method = mono_get_delegate_invoke (klass);
3856 g_ptr_array_add (array, method);
3860 mono_class_setup_methods (klass);
3861 mono_class_setup_vtable (klass);
3862 if (mono_class_has_failure (klass))
3865 if (is_generic_parameter (&klass->byval_arg))
3866 nslots = mono_class_get_vtable_size (klass->parent);
3868 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3869 if (nslots >= sizeof (method_slots_default) * 8) {
3870 method_slots = g_new0 (guint32, nslots / 32 + 1);
3872 method_slots = method_slots_default;
3873 memset (method_slots, 0, sizeof (method_slots_default));
3876 mono_class_setup_methods (klass);
3877 mono_class_setup_vtable (klass);
3878 if (mono_class_has_failure (klass))
3882 while ((method = mono_class_get_methods (klass, &iter))) {
3884 if (method->slot != -1) {
3885 g_assert (method->slot < nslots);
3886 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3888 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3889 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3892 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3894 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3895 if (bflags & BFLAGS_Public)
3897 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3903 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3904 if (bflags & BFLAGS_Static)
3905 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3908 if (bflags & BFLAGS_Instance)
3916 if (compare_func (name, method->name))
3921 g_ptr_array_add (array, method);
3923 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3925 if (method_slots != method_slots_default)
3926 g_free (method_slots);
3931 if (method_slots != method_slots_default)
3932 g_free (method_slots);
3933 g_ptr_array_free (array, TRUE);
3935 g_assert (mono_class_has_failure (klass));
3936 mono_error_set_for_class_failure (error, klass);
3940 ICALL_EXPORT GPtrArray*
3941 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionTypeHandle ref_type, const char *mname, guint32 bflags, MonoBoolean ignore_case, MonoError *error)
3943 mono_error_init (error);
3944 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3946 MonoClass *klass = mono_class_from_mono_type (type);
3948 return g_ptr_array_new ();
3951 return mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, error);
3954 ICALL_EXPORT GPtrArray*
3955 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionTypeHandle ref_type, guint32 bflags, MonoError *error)
3957 mono_error_init (error);
3958 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3960 return g_ptr_array_new ();
3963 MonoClass *startklass, *klass;
3964 klass = startklass = mono_class_from_mono_type (type);
3966 mono_class_setup_methods (klass);
3967 if (mono_class_has_failure (klass)) {
3968 mono_error_set_for_class_failure (error, klass);
3973 GPtrArray *res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3976 gpointer iter = NULL;
3977 while ((method = mono_class_get_methods (klass, &iter))) {
3979 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3981 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3982 if (bflags & BFLAGS_Public)
3985 if (bflags & BFLAGS_NonPublic)
3991 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3992 if (bflags & BFLAGS_Static)
3993 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3996 if (bflags & BFLAGS_Instance)
4002 g_ptr_array_add (res_array, method);
4009 property_hash (gconstpointer data)
4011 MonoProperty *prop = (MonoProperty*)data;
4013 return g_str_hash (prop->name);
4017 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4019 if (method1->slot != -1 && method1->slot == method2->slot)
4022 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4023 if (method1->is_inflated)
4024 method1 = ((MonoMethodInflated*) method1)->declaring;
4025 if (method2->is_inflated)
4026 method2 = ((MonoMethodInflated*) method2)->declaring;
4029 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4033 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4035 // Properties are hide-by-name-and-signature
4036 if (!g_str_equal (prop1->name, prop2->name))
4039 /* If we see a property in a generic method, we want to
4040 compare the generic signatures, not the inflated signatures
4041 because we might conflate two properties that were
4045 public T this[T t] { getter { return t; } } // method 1
4046 public U this[U u] { getter { return u; } } // method 2
4049 If we see int Foo<int,int>::Item[int] we need to know if
4050 the indexer came from method 1 or from method 2, and we
4051 shouldn't conflate them. (Bugzilla 36283)
4053 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4056 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4063 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4068 return method_nonpublic (accessor, start_klass);
4071 ICALL_EXPORT GPtrArray*
4072 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionTypeHandle ref_type, gchar *propname, guint32 bflags, MonoBoolean ignore_case, MonoError *error)
4074 mono_error_init (error);
4075 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4079 return g_ptr_array_new ();
4083 MonoClass *startklass, *klass;
4084 klass = startklass = mono_class_from_mono_type (type);
4086 int (*compare_func) (const char *s1, const char *s2) = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4088 GPtrArray *res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4090 GHashTable *properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4093 mono_class_setup_methods (klass);
4094 mono_class_setup_vtable (klass);
4095 if (mono_class_has_failure (klass)) {
4096 mono_error_set_for_class_failure (error, klass);
4101 gpointer iter = NULL;
4102 while ((prop = mono_class_get_properties (klass, &iter))) {
4104 MonoMethod *method = prop->get;
4109 flags = method->flags;
4110 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4111 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4112 if (bflags & BFLAGS_Public)
4114 } else if (bflags & BFLAGS_NonPublic) {
4115 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4116 property_accessor_nonpublic(prop->set, startklass == klass)) {
4123 if (flags & METHOD_ATTRIBUTE_STATIC) {
4124 if (bflags & BFLAGS_Static)
4125 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4128 if (bflags & BFLAGS_Instance)
4136 if (propname != NULL && compare_func (propname, prop->name))
4139 if (g_hash_table_lookup (properties, prop))
4142 g_ptr_array_add (res_array, prop);
4144 g_hash_table_insert (properties, prop, prop);
4146 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4149 g_hash_table_destroy (properties);
4156 g_hash_table_destroy (properties);
4157 g_ptr_array_free (res_array, TRUE);
4163 event_hash (gconstpointer data)
4165 MonoEvent *event = (MonoEvent*)data;
4167 return g_str_hash (event->name);
4171 event_equal (MonoEvent *event1, MonoEvent *event2)
4173 // Events are hide-by-name
4174 return g_str_equal (event1->name, event2->name);
4177 ICALL_EXPORT GPtrArray*
4178 ves_icall_RuntimeType_GetEvents_native (MonoReflectionTypeHandle ref_type, char *utf8_name, guint32 bflags, MonoError *error)
4180 mono_error_init (error);
4181 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4184 return g_ptr_array_new ();
4187 int (*compare_func) (const char *s1, const char *s2) = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4189 GPtrArray *res_array = g_ptr_array_sized_new (4);
4191 MonoClass *startklass, *klass;
4192 klass = startklass = mono_class_from_mono_type (type);
4194 GHashTable *events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4196 mono_class_setup_methods (klass);
4197 mono_class_setup_vtable (klass);
4198 if (mono_class_has_failure (klass)) {
4199 mono_error_set_for_class_failure (error, klass);
4204 gpointer iter = NULL;
4205 while ((event = mono_class_get_events (klass, &iter))) {
4207 MonoMethod *method = event->add;
4209 method = event->remove;
4211 method = event->raise;
4213 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4214 if (bflags & BFLAGS_Public)
4216 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4217 if (bflags & BFLAGS_NonPublic)
4222 if (bflags & BFLAGS_NonPublic)
4228 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4229 if (bflags & BFLAGS_Static)
4230 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4233 if (bflags & BFLAGS_Instance)
4238 if (bflags & BFLAGS_Instance)
4243 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4246 if (g_hash_table_lookup (events, event))
4249 g_ptr_array_add (res_array, event);
4251 g_hash_table_insert (events, event, event);
4253 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4256 g_hash_table_destroy (events);
4262 g_hash_table_destroy (events);
4264 g_ptr_array_free (res_array, TRUE);
4269 ICALL_EXPORT GPtrArray *
4270 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionTypeHandle ref_type, char *str, guint32 bflags, MonoError *error)
4272 mono_error_init (error);
4273 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4276 return g_ptr_array_new ();
4279 MonoClass *klass = mono_class_from_mono_type (type);
4282 * If a nested type is generic, return its generic type definition.
4283 * Note that this means that the return value is essentially the set
4284 * of nested types of the generic type definition of @klass.
4286 * A note in MSDN claims that a generic type definition can have
4287 * nested types that aren't generic. In any case, the container of that
4288 * nested type would be the generic type definition.
4290 if (mono_class_is_ginst (klass))
4291 klass = mono_class_get_generic_class (klass)->container_class;
4293 GPtrArray *res_array = g_ptr_array_new ();
4296 gpointer iter = NULL;
4297 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4299 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4300 if (bflags & BFLAGS_Public)
4303 if (bflags & BFLAGS_NonPublic)
4309 if (str != NULL && strcmp (nested->name, str))
4312 g_ptr_array_add (res_array, &nested->byval_arg);
4319 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4321 HANDLE_FUNCTION_ENTER ();
4322 mono_error_init (error);
4323 MonoType *type = NULL;
4324 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4325 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4326 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4327 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4328 HANDLE_FUNCTION_RETURN_VAL (type);
4332 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4334 HANDLE_FUNCTION_ENTER ();
4335 mono_error_init (error);
4336 MonoType *type = NULL;
4337 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4338 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4339 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4340 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4341 HANDLE_FUNCTION_RETURN_VAL (type);
4344 ICALL_EXPORT MonoReflectionTypeHandle
4345 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4347 mono_error_init (error);
4349 MonoTypeNameParse info;
4350 gboolean type_resolve;
4352 /* On MS.NET, this does not fire a TypeResolve event */
4353 type_resolve = TRUE;
4354 char *str = mono_string_handle_to_utf8 (name, error);
4358 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4359 if (!mono_reflection_parse_type (str, &info)) {
4361 mono_reflection_free_type_info (&info);
4363 mono_error_set_argument (error, "name", "failed to parse the type");
4366 /*g_print ("failed parse\n");*/
4367 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4370 if (info.assembly.name) {
4372 mono_reflection_free_type_info (&info);
4374 /* 1.0 and 2.0 throw different exceptions */
4375 if (mono_defaults.generic_ilist_class)
4376 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4378 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4381 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4384 MonoType *type = NULL;
4385 if (!MONO_HANDLE_IS_NULL (module)) {
4386 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4388 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4389 if (!is_ok (error)) {
4391 mono_reflection_free_type_info (&info);
4397 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4398 if (assembly_is_dynamic (assembly)) {
4399 /* Enumerate all modules */
4400 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4401 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4404 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4405 MONO_HANDLE_GET (modules, abuilder, modules);
4406 if (!MONO_HANDLE_IS_NULL (modules)) {
4407 int n = mono_array_handle_length (modules);
4408 for (i = 0; i < n; ++i) {
4409 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4410 if (!is_ok (error)) {
4412 mono_reflection_free_type_info (&info);
4420 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4421 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4422 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4423 int n = mono_array_handle_length (loaded_modules);
4424 for (i = 0; i < n; ++i) {
4425 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4427 if (!is_ok (error)) {
4429 mono_reflection_free_type_info (&info);
4438 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4439 if (!is_ok (error)) {
4441 mono_reflection_free_type_info (&info);
4447 mono_reflection_free_type_info (&info);
4451 MonoError inner_error;
4452 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4453 mono_error_assert_ok (&inner_error);
4454 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4455 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4456 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4460 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4463 if (type->type == MONO_TYPE_CLASS) {
4464 MonoClass *klass = mono_type_get_class (type);
4466 /* need to report exceptions ? */
4467 if (throwOnError && mono_class_has_failure (klass)) {
4468 /* report SecurityException (or others) that occured when loading the assembly */
4469 mono_error_set_for_class_failure (error, klass);
4474 /* g_print ("got it\n"); */
4475 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4477 g_assert (!is_ok (error));
4478 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4482 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4485 gchar *shadow_ini_file;
4488 /* Check for shadow-copied assembly */
4489 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4490 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4492 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4493 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4499 g_free (shadow_ini_file);
4500 if (content != NULL) {
4503 *filename = content;
4510 ICALL_EXPORT MonoStringHandle
4511 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4513 mono_error_init (error);
4514 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4515 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4519 if (g_path_is_absolute (mass->image->name)) {
4520 absolute = g_strdup (mass->image->name);
4521 dirname = g_path_get_dirname (absolute);
4523 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4524 dirname = g_strdup (mass->basedir);
4527 replace_shadow_path (domain, dirname, &absolute);
4530 mono_icall_make_platform_path (absolute);
4534 uri = g_filename_to_uri (absolute, NULL, NULL);
4536 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4537 uri = g_strconcat (prepend, absolute, NULL);
4542 MonoStringHandle res;
4544 res = mono_string_new_handle (domain, uri, error);
4547 res = MONO_HANDLE_NEW (MonoString, NULL);
4552 ICALL_EXPORT MonoBoolean
4553 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4555 mono_error_init (error);
4556 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4558 return mass->in_gac;
4561 ICALL_EXPORT MonoReflectionAssemblyHandle
4562 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4565 MonoImageOpenStatus status;
4566 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4568 name = mono_string_handle_to_utf8 (mname, error);
4571 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4577 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4582 ICALL_EXPORT MonoStringHandle
4583 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4585 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4586 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4587 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4590 ICALL_EXPORT MonoBoolean
4591 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4593 mono_error_init (error);
4594 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4595 return assembly->ref_only;
4598 ICALL_EXPORT MonoStringHandle
4599 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4601 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4602 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4604 return mono_string_new_handle (domain, assembly->image->version, error);
4607 ICALL_EXPORT MonoReflectionMethodHandle
4608 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4610 mono_error_init (error);
4611 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4612 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4615 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4616 guint32 token = mono_image_get_entry_point (assembly->image);
4620 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4624 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4629 ICALL_EXPORT MonoReflectionModuleHandle
4630 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4632 mono_error_init (error);
4633 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4634 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4635 return mono_module_get_object_handle (domain, a->image, error);
4639 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4641 HANDLE_FUNCTION_ENTER ();
4642 mono_error_init (error);
4643 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4644 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4647 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4649 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4652 ICALL_EXPORT MonoArrayHandle
4653 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4655 mono_error_init (error);
4656 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4657 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4658 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4659 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4664 for (i = 0; i < table->rows; ++i) {
4665 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4670 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4673 ICALL_EXPORT MonoStringHandle
4674 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4676 char *guid = mono_runtime_get_aotid ();
4679 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4684 static MonoAssemblyName*
4685 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4687 mono_error_init (error);
4688 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4690 mono_assembly_get_assemblyref (image, i, aname);
4691 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4692 /* name and culture are pointers into the image tables, but we need
4693 * real malloc'd strings (so that we can g_free() them later from
4694 * Mono.RuntimeMarshal.FreeAssemblyName) */
4695 aname->name = g_strdup (aname->name);
4696 aname->culture = g_strdup (aname->culture);
4697 /* Don't need the hash value in managed */
4698 aname->hash_value = NULL;
4699 aname->hash_len = 0;
4700 g_assert (aname->public_key == NULL);
4702 /* note: this function doesn't return the codebase on purpose (i.e. it can
4703 be used under partial trust as path information isn't present). */
4707 ICALL_EXPORT GPtrArray*
4708 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4710 mono_error_init (error);
4711 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4712 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4713 MonoImage *image = ass->image;
4715 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4716 int count = t->rows;
4718 GPtrArray *result = g_ptr_array_sized_new (count);
4720 for (int i = 0; i < count; i++) {
4721 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4724 g_ptr_array_add (result, aname);
4729 /* move this in some file in mono/util/ */
4731 g_concat_dir_and_file (const char *dir, const char *file)
4733 g_return_val_if_fail (dir != NULL, NULL);
4734 g_return_val_if_fail (file != NULL, NULL);
4737 * If the directory name doesn't have a / on the end, we need
4738 * to add one so we get a proper path to the file
4740 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4741 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4743 return g_strconcat (dir, file, NULL);
4747 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4749 mono_error_init (error);
4750 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4751 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4752 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4754 guint32 cols [MONO_MANIFEST_SIZE];
4755 guint32 impl, file_idx;
4759 char *n = mono_string_handle_to_utf8 (name, error);
4760 return_val_if_nok (error, NULL);
4762 for (i = 0; i < table->rows; ++i) {
4763 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4764 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4765 if (strcmp (val, n) == 0)
4769 if (i == table->rows)
4772 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4775 * this code should only be called after obtaining the
4776 * ResourceInfo and handling the other cases.
4778 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4779 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4781 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4782 if (!is_ok (error) || !module)
4786 module = assembly->image;
4789 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4792 MONO_HANDLE_ASSIGN (ref_module, rm);
4794 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4798 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4800 HANDLE_FUNCTION_ENTER ();
4801 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4802 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4803 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4805 guint32 cols [MONO_MANIFEST_SIZE];
4806 guint32 file_cols [MONO_FILE_SIZE];
4810 gboolean result = FALSE;
4812 n = mono_string_handle_to_utf8 (name, error);
4816 for (i = 0; i < table->rows; ++i) {
4817 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4818 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4819 if (strcmp (val, n) == 0)
4823 if (i == table->rows)
4826 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4827 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4830 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4831 case MONO_IMPLEMENTATION_FILE:
4832 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4833 table = &assembly->image->tables [MONO_TABLE_FILE];
4834 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4835 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4836 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4837 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4838 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4840 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4843 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4844 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4845 mono_assembly_load_reference (assembly->image, i - 1);
4846 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4847 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4850 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4853 MONO_HANDLE_SET (info, assembly, assm_obj);
4855 /* Obtain info recursively */
4856 get_manifest_resource_info_internal (assm_obj, name, info, error);
4859 guint32 location = MONO_HANDLE_GETVAL (info, location);
4860 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4861 MONO_HANDLE_SETVAL (info, location, guint32, location);
4864 case MONO_IMPLEMENTATION_EXP_TYPE:
4865 g_assert_not_reached ();
4872 HANDLE_FUNCTION_RETURN_VAL (result);
4875 ICALL_EXPORT gboolean
4876 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4878 mono_error_init (error);
4879 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4883 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4885 HANDLE_FUNCTION_ENTER();
4886 mono_error_init (error);
4887 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4888 char *n = g_concat_dir_and_file (assembly->basedir, val);
4889 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4893 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4895 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4898 ICALL_EXPORT MonoObjectHandle
4899 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4901 mono_error_init (error);
4902 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4903 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4904 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4907 /* check hash if needed */
4908 if (!MONO_HANDLE_IS_NULL(name)) {
4909 char *n = mono_string_handle_to_utf8 (name, error);
4913 for (i = 0; i < table->rows; ++i) {
4914 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4915 if (strcmp (val, n) == 0) {
4917 n = g_concat_dir_and_file (assembly->basedir, val);
4918 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4922 return MONO_HANDLE_CAST (MonoObject, fn);
4930 for (i = 0; i < table->rows; ++i) {
4931 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4935 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4940 for (i = 0; i < table->rows; ++i) {
4941 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4942 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4947 return MONO_HANDLE_CAST (MonoObject, result);
4953 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4955 HANDLE_FUNCTION_ENTER ();
4956 mono_error_init (error);
4958 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4962 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4967 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4971 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4973 HANDLE_FUNCTION_ENTER ();
4974 mono_error_init (error);
4976 guint32 cols [MONO_FILE_SIZE];
4977 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4978 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4979 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4982 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4984 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4988 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4989 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4992 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
4995 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4999 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5002 ICALL_EXPORT MonoArrayHandle
5003 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5005 mono_error_init (error);
5006 MonoDomain *domain = mono_domain_get();
5007 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5009 int i, j, file_count = 0;
5010 MonoImage **modules;
5011 guint32 module_count, real_module_count;
5012 MonoTableInfo *table;
5013 MonoImage *image = assembly->image;
5015 g_assert (image != NULL);
5016 g_assert (!assembly_is_dynamic (assembly));
5018 table = &image->tables [MONO_TABLE_FILE];
5019 file_count = table->rows;
5021 modules = image->modules;
5022 module_count = image->module_count;
5024 real_module_count = 0;
5025 for (i = 0; i < module_count; ++i)
5027 real_module_count ++;
5029 klass = mono_class_get_module_class ();
5030 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5034 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5038 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5041 for (i = 0; i < module_count; ++i)
5042 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5045 for (i = 0; i < file_count; ++i, ++j) {
5046 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5052 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5055 ICALL_EXPORT MonoReflectionMethodHandle
5056 ves_icall_GetCurrentMethod (MonoError *error)
5058 mono_error_init (error);
5060 MonoMethod *m = mono_method_get_last_managed ();
5063 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5064 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5067 while (m->is_inflated)
5068 m = ((MonoMethodInflated*)m)->declaring;
5070 return mono_method_get_object_handle (mono_domain_get (), m, NULL, error);
5075 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5078 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5081 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5082 //method is inflated, we should inflate it on the other class
5083 MonoGenericContext ctx;
5084 ctx.method_inst = inflated->context.method_inst;
5085 ctx.class_inst = inflated->context.class_inst;
5086 if (mono_class_is_ginst (klass))
5087 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5088 else if (mono_class_is_gtd (klass))
5089 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5090 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5091 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5095 mono_class_setup_methods (method->klass);
5096 if (mono_class_has_failure (method->klass))
5098 int mcount = mono_class_get_method_count (method->klass);
5099 for (i = 0; i < mcount; ++i) {
5100 if (method->klass->methods [i] == method) {
5105 mono_class_setup_methods (klass);
5106 if (mono_class_has_failure (klass))
5108 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5109 return klass->methods [offset];
5112 ICALL_EXPORT MonoReflectionMethodHandle
5113 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check, MonoError *error)
5115 mono_error_init (error);
5117 if (type && generic_check) {
5118 klass = mono_class_from_mono_type (type);
5119 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5120 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5122 if (method->klass != klass) {
5123 method = mono_method_get_equivalent_method (method, klass);
5125 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5128 klass = mono_class_from_mono_type (type);
5130 klass = method->klass;
5131 return mono_method_get_object_handle (mono_domain_get (), method, klass, error);
5134 ICALL_EXPORT MonoReflectionMethodBodyHandle
5135 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method, MonoError *error)
5137 mono_error_init (error);
5138 return mono_method_body_get_object_handle (mono_domain_get (), method, error);
5141 ICALL_EXPORT MonoReflectionAssemblyHandle
5142 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5144 mono_error_init (error);
5146 MonoMethod *dest = NULL;
5147 mono_stack_walk_no_il (get_executing, &dest);
5149 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5153 ICALL_EXPORT MonoReflectionAssemblyHandle
5154 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5156 mono_error_init (error);
5158 MonoDomain* domain = mono_domain_get ();
5160 if (!domain->entry_assembly)
5161 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5163 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5166 ICALL_EXPORT MonoReflectionAssemblyHandle
5167 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5169 mono_error_init (error);
5174 mono_stack_walk_no_il (get_executing, &dest);
5176 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5180 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5181 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5183 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5186 ICALL_EXPORT MonoStringHandle
5187 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5188 gboolean assembly_qualified, MonoError *error)
5190 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5191 MonoType *type = MONO_HANDLE_RAW (object)->type;
5192 MonoTypeNameFormat format;
5193 MonoStringHandle res;
5197 format = assembly_qualified ?
5198 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5199 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5201 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5203 name = mono_type_get_name_full (type, format);
5205 return NULL_HANDLE_STRING;
5207 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5209 return NULL_HANDLE_STRING;
5212 res = mono_string_new_handle (domain, name, error);
5219 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionTypeHandle rfield, MonoError *error)
5221 mono_error_init (error);
5222 MonoType *type = MONO_HANDLE_GETVAL (rfield, type);
5223 MonoClass *klass = mono_class_from_mono_type (type);
5225 mono_class_init_checked (klass, error);
5228 return mono_security_core_clr_class_level (klass);
5232 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5234 MonoClassField *field = rfield->field;
5235 return mono_security_core_clr_field_level (field, TRUE);
5239 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5241 MonoMethod *method = rfield->method;
5242 return mono_security_core_clr_method_level (method, TRUE);
5245 ICALL_EXPORT MonoStringHandle
5246 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5248 mono_error_init (error);
5249 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5250 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5253 name = mono_stringify_assembly_name (&mass->aname);
5254 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5259 ICALL_EXPORT MonoAssemblyName *
5260 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5262 return &mass->aname;
5266 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5269 MonoImageOpenStatus status = MONO_IMAGE_OK;
5270 char *codebase = NULL;
5275 mono_error_init (error);
5277 filename = mono_string_handle_to_utf8 (fname, error);
5278 return_if_nok (error);
5280 dirname = g_path_get_dirname (filename);
5281 replace_shadow_path (mono_domain_get (), dirname, &filename);
5284 image = mono_image_open_full (filename, &status, TRUE);
5287 if (status == MONO_IMAGE_IMAGE_INVALID)
5288 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5290 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5295 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5297 mono_image_close (image);
5299 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5303 if (filename != NULL && *filename != '\0') {
5306 codebase = g_strdup (filename);
5308 mono_icall_make_platform_path (codebase);
5310 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5312 result = g_strconcat (prepend, codebase, NULL);
5316 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5319 mono_image_close (image);
5323 ICALL_EXPORT MonoBoolean
5324 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5325 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5327 mono_error_init (error);
5328 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5329 MonoBoolean result = FALSE;
5330 MonoDeclSecurityEntry entry;
5332 /* SecurityAction.RequestMinimum */
5333 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5334 *minimum = entry.blob;
5335 *minLength = entry.size;
5338 /* SecurityAction.RequestOptional */
5339 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5340 *optional = entry.blob;
5341 *optLength = entry.size;
5344 /* SecurityAction.RequestRefuse */
5345 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5346 *refused = entry.blob;
5347 *refLength = entry.size;
5355 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5357 guint32 attrs, visibility;
5359 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5360 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5361 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5364 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5370 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5372 mono_error_init (error);
5373 HANDLE_FUNCTION_ENTER ();
5374 MonoError klass_error;
5375 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5378 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5379 return_if_nok (error);
5381 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5383 MonoException *ex = mono_error_convert_to_exception (error);
5384 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5386 HANDLE_FUNCTION_RETURN ();
5389 static MonoArrayHandle
5390 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5392 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5395 mono_error_init (error);
5397 /* we start the count from 1 because we skip the special type <Module> */
5400 for (i = 1; i < tdef->rows; ++i) {
5401 if (mono_module_type_is_visible (tdef, image, i + 1))
5405 count = tdef->rows - 1;
5407 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5408 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5409 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5410 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5412 for (i = 1; i < tdef->rows; ++i) {
5413 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5414 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5415 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5424 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5426 HANDLE_FUNCTION_ENTER ();
5427 mono_error_init (error);
5428 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5429 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5433 /* Append the new types to the end of the array */
5434 if (mono_array_handle_length (res2) > 0) {
5437 len1 = mono_array_handle_length (res);
5438 len2 = mono_array_handle_length (res2);
5440 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5444 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5445 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5446 MONO_HANDLE_ASSIGN (res, res3);
5448 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5452 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5453 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5454 MONO_HANDLE_ASSIGN (exceptions, ex3);
5457 HANDLE_FUNCTION_RETURN ();
5461 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5463 HANDLE_FUNCTION_ENTER ();
5464 MonoError unboxed_error;
5465 mono_error_init (&unboxed_error);
5466 mono_error_set_for_class_failure (&unboxed_error, klass);
5468 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5469 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5470 HANDLE_FUNCTION_RETURN ();
5473 ICALL_EXPORT MonoArrayHandle
5474 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5476 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5479 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5480 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5482 g_assert (!assembly_is_dynamic (assembly));
5483 MonoImage *image = assembly->image;
5484 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5485 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5486 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5488 /* Append data from all modules in the assembly */
5489 for (i = 0; i < table->rows; ++i) {
5490 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5491 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5492 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5495 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5496 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5501 /* the ReflectionTypeLoadException must have all the types (Types property),
5502 * NULL replacing types which throws an exception. The LoaderException must
5503 * contain all exceptions for NULL items.
5506 int len = mono_array_handle_length (res);
5510 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5511 for (i = 0; i < len; i++) {
5512 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5514 if (!MONO_HANDLE_IS_NULL (t)) {
5515 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5516 if ((klass != NULL) && mono_class_has_failure (klass)) {
5517 /* keep the class in the list */
5518 list = g_list_append (list, klass);
5519 /* and replace Type with NULL */
5520 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5527 if (list || ex_count) {
5529 int j, length = g_list_length (list) + ex_count;
5531 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5532 if (!is_ok (error)) {
5534 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5536 /* Types for which mono_class_get_checked () succeeded */
5537 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5538 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5539 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5541 /* Types for which it don't */
5542 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5543 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5544 if (!MONO_HANDLE_IS_NULL (exc)) {
5545 g_assert (i < length);
5546 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5553 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5554 if (!is_ok (error)) {
5555 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5557 mono_error_set_exception_handle (error, exc);
5558 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5565 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5567 mono_assembly_name_free (aname);
5572 ICALL_EXPORT gboolean
5573 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5575 *is_version_definited = *is_token_defined = FALSE;
5577 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5580 ICALL_EXPORT MonoReflectionTypeHandle
5581 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5583 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5584 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5589 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5591 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5592 /* These images do not have a global type */
5595 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5599 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5605 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5607 /*if (module->image)
5608 mono_image_close (module->image);*/
5611 ICALL_EXPORT MonoStringHandle
5612 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5614 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5615 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5618 return mono_string_new_handle (domain, image->guid, error);
5622 static inline gpointer
5623 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5625 return (gpointer) (-1);
5627 #endif /* HOST_WIN32 */
5629 ICALL_EXPORT gpointer
5630 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5632 return mono_icall_module_get_hinstance (module);
5636 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5638 if (image_is_dynamic (image)) {
5639 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5640 *pe_kind = dyn->pe_kind;
5641 *machine = dyn->machine;
5644 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5645 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5650 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5652 return (image->md_version_major << 16) | (image->md_version_minor);
5655 ICALL_EXPORT MonoArrayHandle
5656 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5658 mono_error_init (error);
5660 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5661 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5664 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5667 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5668 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5669 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5671 int n = mono_array_handle_length (exceptions);
5672 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5673 for (int i = 0; i < n; ++i) {
5674 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5675 if (!MONO_HANDLE_IS_NULL (ex)) {
5676 mono_error_set_exception_handle (error, ex);
5677 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5685 mono_memberref_is_method (MonoImage *image, guint32 token)
5687 if (!image_is_dynamic (image)) {
5688 guint32 cols [MONO_MEMBERREF_SIZE];
5690 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5691 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5692 mono_metadata_decode_blob_size (sig, &sig);
5693 return (*sig != 0x6);
5696 MonoClass *handle_class;
5698 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5699 mono_error_cleanup (&error); /* just probing, ignore error */
5703 return mono_defaults.methodhandle_class == handle_class;
5707 static MonoGenericInst *
5708 get_generic_inst_from_array_handle (MonoArrayHandle type_args)
5710 int type_argc = mono_array_handle_length (type_args);
5711 int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
5713 MonoGenericInst *ginst = (MonoGenericInst *)g_alloca (size);
5714 memset (ginst, 0, sizeof (MonoGenericInst));
5715 ginst->type_argc = type_argc;
5716 for (int i = 0; i < type_argc; i++) {
5717 MONO_HANDLE_ARRAY_GETVAL (ginst->type_argv[i], type_args, MonoType*, i);
5719 ginst->is_open = FALSE;
5720 for (int i = 0; i < type_argc; i++) {
5721 if (mono_class_is_open_constructed_type (ginst->type_argv[i])) {
5722 ginst->is_open = TRUE;
5727 return mono_metadata_get_canonical_generic_inst (ginst);
5731 init_generic_context_from_args_handles (MonoGenericContext *context, MonoArrayHandle type_args, MonoArrayHandle method_args)
5733 if (!MONO_HANDLE_IS_NULL (type_args)) {
5734 context->class_inst = get_generic_inst_from_array_handle (type_args);
5736 context->class_inst = NULL;
5738 if (!MONO_HANDLE_IS_NULL (method_args)) {
5739 context->method_inst = get_generic_inst_from_array_handle (method_args);
5741 context->method_inst = NULL;
5747 module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5749 HANDLE_FUNCTION_ENTER ();
5750 mono_error_init (error);
5751 MonoType *result = NULL;
5753 int table = mono_metadata_token_table (token);
5754 int index = mono_metadata_token_index (token);
5755 MonoGenericContext context;
5757 *resolve_error = ResolveTokenError_Other;
5759 /* Validate token */
5760 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5761 (table != MONO_TABLE_TYPESPEC)) {
5762 *resolve_error = ResolveTokenError_BadTable;
5766 if (image_is_dynamic (image)) {
5767 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5768 MonoError inner_error;
5769 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5770 mono_error_cleanup (&inner_error);
5771 result = klass ? &klass->byval_arg : NULL;
5775 init_generic_context_from_args_handles (&context, type_args, method_args);
5776 MonoError inner_error;
5777 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5778 mono_error_cleanup (&inner_error);
5779 result = klass ? &klass->byval_arg : NULL;
5783 if ((index <= 0) || (index > image->tables [table].rows)) {
5784 *resolve_error = ResolveTokenError_OutOfRange;
5788 init_generic_context_from_args_handles (&context, type_args, method_args);
5789 klass = mono_class_get_checked (image, token, error);
5791 klass = mono_class_inflate_generic_class_checked (klass, &context, error);
5796 result = &klass->byval_arg;
5798 HANDLE_FUNCTION_RETURN_VAL (result);
5801 ICALL_EXPORT MonoType*
5802 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5804 return module_resolve_type_token (image, token, type_args, method_args, resolve_error, error);
5808 module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5810 HANDLE_FUNCTION_ENTER ();
5811 mono_error_init (error);
5812 MonoMethod *method = NULL;
5813 int table = mono_metadata_token_table (token);
5814 int index = mono_metadata_token_index (token);
5815 MonoGenericContext context;
5817 *resolve_error = ResolveTokenError_Other;
5819 /* Validate token */
5820 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5821 (table != MONO_TABLE_MEMBERREF)) {
5822 *resolve_error = ResolveTokenError_BadTable;
5826 if (image_is_dynamic (image)) {
5827 if (table == MONO_TABLE_METHOD) {
5828 MonoError inner_error;
5829 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5830 mono_error_cleanup (&inner_error);
5834 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5835 *resolve_error = ResolveTokenError_BadTable;
5839 init_generic_context_from_args_handles (&context, type_args, method_args);
5840 MonoError inner_error;
5841 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5842 mono_error_cleanup (&inner_error);
5846 if ((index <= 0) || (index > image->tables [table].rows)) {
5847 *resolve_error = ResolveTokenError_OutOfRange;
5850 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5851 *resolve_error = ResolveTokenError_BadTable;
5855 init_generic_context_from_args_handles (&context, type_args, method_args);
5856 method = mono_get_method_checked (image, token, NULL, &context, error);
5859 HANDLE_FUNCTION_RETURN_VAL (method);
5862 ICALL_EXPORT MonoMethod*
5863 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5865 return module_resolve_method_token (image, token, type_args, method_args, resolve_error, error);
5868 ICALL_EXPORT MonoString*
5869 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5872 int index = mono_metadata_token_index (token);
5874 *resolve_error = ResolveTokenError_Other;
5876 /* Validate token */
5877 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5878 *resolve_error = ResolveTokenError_BadTable;
5882 if (image_is_dynamic (image)) {
5883 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5884 mono_error_cleanup (&error);
5888 if ((index <= 0) || (index >= image->heap_us.size)) {
5889 *resolve_error = ResolveTokenError_OutOfRange;
5893 /* FIXME: What to do if the index points into the middle of a string ? */
5895 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5896 mono_error_set_pending_exception (&error);
5900 static MonoClassField*
5901 module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5903 HANDLE_FUNCTION_ENTER ();
5905 int table = mono_metadata_token_table (token);
5906 int index = mono_metadata_token_index (token);
5907 MonoGenericContext context;
5908 MonoClassField *field = NULL;
5910 mono_error_init (error);
5911 *resolve_error = ResolveTokenError_Other;
5913 /* Validate token */
5914 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5915 *resolve_error = ResolveTokenError_BadTable;
5919 if (image_is_dynamic (image)) {
5920 if (table == MONO_TABLE_FIELD) {
5921 MonoError inner_error;
5922 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5923 mono_error_cleanup (&inner_error);
5927 if (mono_memberref_is_method (image, token)) {
5928 *resolve_error = ResolveTokenError_BadTable;
5932 init_generic_context_from_args_handles (&context, type_args, method_args);
5933 MonoError inner_error;
5934 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5935 mono_error_cleanup (&inner_error);
5939 if ((index <= 0) || (index > image->tables [table].rows)) {
5940 *resolve_error = ResolveTokenError_OutOfRange;
5943 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5944 *resolve_error = ResolveTokenError_BadTable;
5948 init_generic_context_from_args_handles (&context, type_args, method_args);
5949 field = mono_field_from_token_checked (image, token, &klass, &context, error);
5952 HANDLE_FUNCTION_RETURN_VAL (field);
5955 ICALL_EXPORT MonoClassField*
5956 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5958 return module_resolve_field_token (image, token, type_args, method_args, resolve_error, error);
5961 ICALL_EXPORT MonoObjectHandle
5962 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *error, MonoError *merror)
5964 int table = mono_metadata_token_table (token);
5966 mono_error_init (merror);
5967 *error = ResolveTokenError_Other;
5970 case MONO_TABLE_TYPEDEF:
5971 case MONO_TABLE_TYPEREF:
5972 case MONO_TABLE_TYPESPEC: {
5973 MonoType *t = module_resolve_type_token (image, token, type_args, method_args, error, merror);
5975 return MONO_HANDLE_CAST (MonoObject, mono_type_get_object_handle (mono_domain_get (), t, merror));
5980 case MONO_TABLE_METHOD:
5981 case MONO_TABLE_METHODSPEC: {
5982 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
5984 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
5988 case MONO_TABLE_FIELD: {
5989 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
5991 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
5996 case MONO_TABLE_MEMBERREF:
5997 if (mono_memberref_is_method (image, token)) {
5998 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
6000 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
6005 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
6007 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6015 *error = ResolveTokenError_BadTable;
6021 ICALL_EXPORT MonoArrayHandle
6022 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error, MonoError *error)
6024 mono_error_init (error);
6025 int table = mono_metadata_token_table (token);
6026 int idx = mono_metadata_token_index (token);
6027 MonoTableInfo *tables = image->tables;
6031 *resolve_error = ResolveTokenError_OutOfRange;
6033 /* FIXME: Support other tables ? */
6034 if (table != MONO_TABLE_STANDALONESIG)
6035 return MONO_HANDLE_CAST (MonoArray, NULL);
6037 if (image_is_dynamic (image))
6038 return MONO_HANDLE_CAST (MonoArray, NULL);
6040 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6041 return MONO_HANDLE_CAST (MonoArray, NULL);
6043 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6045 ptr = mono_metadata_blob_heap (image, sig);
6046 len = mono_metadata_decode_blob_size (ptr, &ptr);
6048 MonoArrayHandle res = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, len, error);
6050 return MONO_HANDLE_CAST (MonoArray, NULL);
6052 gpointer array_base = MONO_ARRAY_HANDLE_PIN (res, guint8, 0, &h);
6053 memcpy (array_base, ptr, len);
6054 mono_gchandle_free (h);
6058 ICALL_EXPORT MonoBoolean
6059 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionTypeHandle ref_type, MonoError *error)
6061 mono_error_init (error);
6062 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6064 MonoBoolean res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6070 check_for_invalid_type (MonoClass *klass, MonoError *error)
6074 mono_error_init (error);
6076 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6079 name = mono_type_get_full_name (klass);
6080 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6082 ICALL_EXPORT MonoReflectionTypeHandle
6083 ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int rank, MonoError *error)
6085 mono_error_init (error);
6086 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6088 MonoClass *klass = mono_class_from_mono_type (type);
6089 check_for_invalid_type (klass, error);
6091 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6094 if (rank == 0) //single dimentional array
6095 aklass = mono_array_class_get (klass, 1);
6097 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6099 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6100 return mono_type_get_object_handle (domain, &aklass->byval_arg, error);
6103 ICALL_EXPORT MonoReflectionTypeHandle
6104 ves_icall_RuntimeType_make_byref_type (MonoReflectionTypeHandle ref_type, MonoError *error)
6106 mono_error_init (error);
6107 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6109 MonoClass *klass = mono_class_from_mono_type (type);
6110 mono_class_init_checked (klass, error);
6112 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6114 check_for_invalid_type (klass, error);
6116 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6118 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6119 return mono_type_get_object_handle (domain, &klass->this_arg, error);
6122 ICALL_EXPORT MonoReflectionTypeHandle
6123 ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type, MonoError *error)
6125 mono_error_init (error);
6126 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6127 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6128 MonoClass *klass = mono_class_from_mono_type (type);
6129 mono_class_init_checked (klass, error);
6131 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6133 check_for_invalid_type (klass, error);
6135 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6137 MonoClass *pklass = mono_ptr_class_get (type);
6139 return mono_type_get_object_handle (domain, &pklass->byval_arg, error);
6142 ICALL_EXPORT MonoObject *
6143 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6144 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6147 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6148 MonoObject *delegate;
6150 MonoMethod *method = info->method;
6151 MonoMethodSignature *sig = mono_method_signature(method);
6153 mono_class_init_checked (delegate_class, &error);
6154 if (mono_error_set_pending_exception (&error))
6157 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6158 /* FIXME improve this exception message */
6159 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6161 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6162 mono_error_set_pending_exception (&error);
6166 if (mono_security_core_clr_enabled ()) {
6167 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6168 if (throwOnBindFailure)
6169 mono_error_set_pending_exception (&error);
6171 mono_error_cleanup (&error);
6176 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6177 if (!method->is_inflated) {
6178 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"));
6183 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6184 if (mono_error_set_pending_exception (&error))
6187 if (method_is_dynamic (method)) {
6188 /* Creating a trampoline would leak memory */
6189 func = mono_compile_method_checked (method, &error);
6190 if (mono_error_set_pending_exception (&error))
6193 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6194 method = mono_object_get_virtual_method (target, method);
6195 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6196 if (mono_error_set_pending_exception (&error))
6198 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6201 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6202 if (mono_error_set_pending_exception (&error))
6207 ICALL_EXPORT MonoMulticastDelegate *
6208 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6211 MonoMulticastDelegate *ret;
6213 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6215 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6216 if (mono_error_set_pending_exception (&error))
6219 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6224 ICALL_EXPORT MonoReflectionMethod*
6225 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6227 MonoReflectionMethod *ret = NULL;
6229 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6230 mono_error_set_pending_exception (&error);
6236 static inline gint32
6237 mono_array_get_byte_length (MonoArray *array)
6243 klass = array->obj.vtable->klass;
6245 if (array->bounds == NULL)
6246 length = array->max_length;
6249 for (i = 0; i < klass->rank; ++ i)
6250 length *= array->bounds [i].length;
6253 switch (klass->element_class->byval_arg.type) {
6256 case MONO_TYPE_BOOLEAN:
6260 case MONO_TYPE_CHAR:
6268 return length * sizeof (gpointer);
6279 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6281 return mono_array_get_byte_length (array);
6285 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6287 return mono_array_get (array, gint8, idx);
6291 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6293 mono_array_set (array, gint8, idx, value);
6296 ICALL_EXPORT MonoBoolean
6297 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6299 guint8 *src_buf, *dest_buf;
6302 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6306 g_assert (count >= 0);
6308 /* This is called directly from the class libraries without going through the managed wrapper */
6309 MONO_CHECK_ARG_NULL (src, FALSE);
6310 MONO_CHECK_ARG_NULL (dest, FALSE);
6312 /* watch out for integer overflow */
6313 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6316 src_buf = (guint8 *)src->vector + src_offset;
6317 dest_buf = (guint8 *)dest->vector + dest_offset;
6320 memcpy (dest_buf, src_buf, count);
6322 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6327 #ifndef DISABLE_REMOTING
6328 ICALL_EXPORT MonoObjectHandle
6329 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObjectHandle this_obj, MonoStringHandle class_name, MonoError *error)
6331 mono_error_init (error);
6332 MonoDomain *domain = MONO_HANDLE_DOMAIN (this_obj);
6333 MonoRealProxyHandle rp = MONO_HANDLE_CAST (MonoRealProxy, this_obj);
6335 MonoObjectHandle res = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, error));
6339 MonoTransparentProxyHandle tp = MONO_HANDLE_CAST (MonoTransparentProxy, res);
6341 MONO_HANDLE_SET (tp, rp, rp);
6343 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
6344 MONO_HANDLE_GET (reftype, rp, class_to_proxy);
6345 MonoType *type = MONO_HANDLE_GETVAL (reftype, type);
6346 MonoClass *klass = mono_class_from_mono_type (type);
6348 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6349 mono_class_setup_vtable (klass);
6350 if (mono_class_has_failure (klass)) {
6351 mono_error_set_for_class_failure (error, klass);
6355 MonoObjectHandle remoting_obj = mono_object_handle_isinst (this_obj, mono_defaults.iremotingtypeinfo_class, error);
6358 MONO_HANDLE_SETVAL (tp, custom_type_info, MonoBoolean, !MONO_HANDLE_IS_NULL (remoting_obj));
6360 MonoRemoteClass *remote_class = mono_remote_class (domain, class_name, klass, error);
6363 MONO_HANDLE_SETVAL (tp, remote_class, MonoRemoteClass*, remote_class);
6365 MONO_HANDLE_SETVAL (res, vtable, MonoVTable*, mono_remote_class_vtable (domain, remote_class, rp, error));
6371 ICALL_EXPORT MonoReflectionType *
6372 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6375 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6376 mono_error_set_pending_exception (&error);
6382 /* System.Environment */
6385 ves_icall_System_Environment_get_UserName (void)
6387 /* using glib is more portable */
6388 return mono_string_new (mono_domain_get (), g_get_user_name ());
6393 mono_icall_get_machine_name (void)
6395 #if !defined(DISABLE_SOCKETS)
6399 #if defined _SC_HOST_NAME_MAX
6400 n = sysconf (_SC_HOST_NAME_MAX);
6404 buf = g_malloc (n+1);
6406 if (gethostname (buf, n) == 0){
6408 result = mono_string_new (mono_domain_get (), buf);
6415 return mono_string_new (mono_domain_get (), "mono");
6418 #endif /* !HOST_WIN32 */
6420 ICALL_EXPORT MonoString *
6421 ves_icall_System_Environment_get_MachineName (void)
6423 return mono_icall_get_machine_name ();
6428 mono_icall_get_platform (void)
6430 #if defined(__MACH__)
6433 // Notice that the value is hidden from user code, and only exposed
6434 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6435 // define and making assumptions based on Unix/128/4 values before there
6436 // was a MacOS define. Lots of code would assume that not-Unix meant
6437 // Windows, but in this case, it would be OSX.
6445 #endif /* !HOST_WIN32 */
6448 ves_icall_System_Environment_get_Platform (void)
6450 return mono_icall_get_platform ();
6454 static inline MonoString *
6455 mono_icall_get_new_line (void)
6457 return mono_string_new (mono_domain_get (), "\n");
6459 #endif /* !HOST_WIN32 */
6461 ICALL_EXPORT MonoString *
6462 ves_icall_System_Environment_get_NewLine (void)
6464 return mono_icall_get_new_line ();
6468 static inline MonoBoolean
6469 mono_icall_is_64bit_os (void)
6471 #if SIZEOF_VOID_P == 8
6474 #if defined(HAVE_SYS_UTSNAME_H)
6475 struct utsname name;
6477 if (uname (&name) >= 0) {
6478 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6484 #endif /* !HOST_WIN32 */
6486 ICALL_EXPORT MonoBoolean
6487 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6489 return mono_icall_is_64bit_os ();
6492 ICALL_EXPORT MonoStringHandle
6493 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6497 if (utf8_name == NULL)
6498 return NULL_HANDLE_STRING;
6500 value = g_getenv (utf8_name);
6503 return NULL_HANDLE_STRING;
6505 return mono_string_new_handle (mono_domain_get (), value, error);
6509 * There is no standard way to get at environ.
6512 #ifndef __MINGW32_VERSION
6513 #if defined(__APPLE__)
6514 #if defined (TARGET_OSX)
6515 /* Apple defines this in crt_externs.h but doesn't provide that header for
6516 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6517 * in fact exist on all implementations (so far)
6519 gchar ***_NSGetEnviron(void);
6520 #define environ (*_NSGetEnviron())
6522 static char *mono_environ[1] = { NULL };
6523 #define environ mono_environ
6524 #endif /* defined (TARGET_OSX) */
6532 ICALL_EXPORT MonoArray *
6533 ves_icall_System_Environment_GetCoomandLineArgs (void)
6536 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6537 mono_error_set_pending_exception (&error);
6543 mono_icall_get_environment_variable_names (void)
6553 for (e = environ; *e != 0; ++ e)
6556 domain = mono_domain_get ();
6557 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6558 if (mono_error_set_pending_exception (&error))
6562 for (e = environ; *e != 0; ++ e) {
6563 parts = g_strsplit (*e, "=", 2);
6565 str = mono_string_new (domain, *parts);
6566 mono_array_setref (names, n, str);
6576 #endif /* !HOST_WIN32 */
6578 ICALL_EXPORT MonoArray *
6579 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6581 return mono_icall_get_environment_variable_names ();
6586 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6588 gchar *utf8_name, *utf8_value;
6591 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6592 if (mono_error_set_pending_exception (&error))
6595 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6596 g_unsetenv (utf8_name);
6601 utf8_value = mono_string_to_utf8_checked (value, &error);
6602 if (!mono_error_ok (&error)) {
6604 mono_error_set_pending_exception (&error);
6607 g_setenv (utf8_name, utf8_value, TRUE);
6610 g_free (utf8_value);
6612 #endif /* !HOST_WIN32 */
6615 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6617 mono_icall_set_environment_variable (name, value);
6621 ves_icall_System_Environment_Exit (int result)
6623 mono_environment_exitcode_set (result);
6625 /* FIXME: There are some cleanup hangs that should be worked out, but
6626 * if the program is going to exit, everything will be cleaned up when
6627 * NaCl exits anyway.
6629 #ifndef __native_client__
6630 if (!mono_runtime_try_shutdown ())
6631 mono_thread_exit ();
6633 /* Suspend all managed threads since the runtime is going away */
6634 mono_thread_suspend_all_other_threads ();
6636 mono_runtime_quit ();
6639 /* we may need to do some cleanup here... */
6643 ICALL_EXPORT MonoStringHandle
6644 ves_icall_System_Environment_GetGacPath (MonoError *error)
6646 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6650 static inline MonoString *
6651 mono_icall_get_windows_folder_path (int folder)
6653 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6654 return mono_string_new (mono_domain_get (), "");
6656 #endif /* !HOST_WIN32 */
6658 ICALL_EXPORT MonoString*
6659 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6661 return mono_icall_get_windows_folder_path (folder);
6664 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6666 mono_icall_get_logical_drives (void)
6669 gunichar2 buf [256], *ptr, *dname;
6671 guint initial_size = 127, size = 128;
6674 MonoString *drivestr;
6675 MonoDomain *domain = mono_domain_get ();
6681 while (size > initial_size) {
6682 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6683 if (size > initial_size) {
6686 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6687 initial_size = size;
6701 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6702 if (mono_error_set_pending_exception (&error))
6709 while (*u16) { u16++; len ++; }
6710 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6711 if (mono_error_set_pending_exception (&error))
6714 mono_array_setref (result, ndrives++, drivestr);
6724 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6726 ICALL_EXPORT MonoArray *
6727 ves_icall_System_Environment_GetLogicalDrives (void)
6729 return mono_icall_get_logical_drives ();
6732 ICALL_EXPORT MonoString *
6733 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6736 gunichar2 volume_name [MAX_PATH + 1];
6738 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6740 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6741 mono_error_set_pending_exception (&error);
6745 ICALL_EXPORT MonoStringHandle
6746 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6748 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6751 static const char *encodings [] = {
6753 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6754 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6755 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6757 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6758 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6759 "x_unicode_2_0_utf_7",
6761 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6762 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6764 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6767 "unicodefffe", "utf_16be",
6774 * Returns the internal codepage, if the value of "int_code_page" is
6775 * 1 at entry, and we can not compute a suitable code page number,
6776 * returns the code page as a string
6778 ICALL_EXPORT MonoString*
6779 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6784 char *codepage = NULL;
6786 int want_name = *int_code_page;
6789 *int_code_page = -1;
6791 g_get_charset (&cset);
6792 c = codepage = g_strdup (cset);
6793 for (c = codepage; *c; c++){
6794 if (isascii (*c) && isalpha (*c))
6799 /* g_print ("charset: %s\n", cset); */
6801 /* handle some common aliases */
6804 for (i = 0; p != 0; ){
6807 p = encodings [++i];
6810 if (strcmp (p, codepage) == 0){
6811 *int_code_page = code;
6814 p = encodings [++i];
6817 if (strstr (codepage, "utf_8") != NULL)
6818 *int_code_page |= 0x10000000;
6821 if (want_name && *int_code_page == -1)
6822 return mono_string_new (mono_domain_get (), cset);
6827 ICALL_EXPORT MonoBoolean
6828 ves_icall_System_Environment_get_HasShutdownStarted (void)
6830 if (mono_runtime_is_shutting_down ())
6833 if (mono_domain_is_unloading (mono_domain_get ()))
6841 mono_icall_broadcast_setting_change (void)
6845 #endif /* !HOST_WIN32 */
6848 ves_icall_System_Environment_BroadcastSettingChange (void)
6850 mono_icall_broadcast_setting_change ();
6855 ves_icall_System_Environment_get_TickCount (void)
6857 /* this will overflow after ~24 days */
6858 return (gint32) (mono_msec_boottime () & 0xffffffff);
6862 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6867 #ifndef DISABLE_REMOTING
6868 ICALL_EXPORT MonoBoolean
6869 ves_icall_IsTransparentProxy (MonoObject *proxy)
6874 if (mono_object_is_transparent_proxy (proxy))
6880 ICALL_EXPORT MonoReflectionMethod *
6881 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6882 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6884 MonoReflectionMethod *ret = NULL;
6889 MonoMethod **vtable;
6890 MonoMethod *res = NULL;
6892 MONO_CHECK_ARG_NULL (rtype, NULL);
6893 MONO_CHECK_ARG_NULL (rmethod, NULL);
6895 method = rmethod->method;
6896 klass = mono_class_from_mono_type (rtype->type);
6897 mono_class_init_checked (klass, &error);
6898 if (mono_error_set_pending_exception (&error))
6901 if (MONO_CLASS_IS_INTERFACE (klass))
6904 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6907 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6908 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6914 mono_class_setup_vtable (klass);
6915 vtable = klass->vtable;
6917 if (mono_class_is_interface (method->klass)) {
6918 gboolean variance_used = FALSE;
6919 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6920 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6922 res = vtable [offs + method->slot];
6924 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6927 if (method->slot != -1)
6928 res = vtable [method->slot];
6934 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6935 mono_error_set_pending_exception (&error);
6940 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6946 klass = mono_class_from_mono_type (type->type);
6947 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6948 if (!is_ok (&error)) {
6949 mono_error_set_pending_exception (&error);
6953 mono_vtable_set_is_remote (vtable, enable);
6956 #else /* DISABLE_REMOTING */
6959 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6961 g_assert_not_reached ();
6966 ICALL_EXPORT MonoObject *
6967 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6974 domain = mono_object_domain (type);
6975 klass = mono_class_from_mono_type (type->type);
6976 mono_class_init_checked (klass, &error);
6977 if (mono_error_set_pending_exception (&error))
6980 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6981 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6985 if (klass->rank >= 1) {
6986 g_assert (klass->rank == 1);
6987 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6988 mono_error_set_pending_exception (&error);
6991 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6992 if (!is_ok (&error)) {
6993 mono_error_set_pending_exception (&error);
6996 /* Bypass remoting object creation check */
6997 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6998 mono_error_set_pending_exception (&error);
7004 ICALL_EXPORT MonoStringHandle
7005 ves_icall_System_IO_get_temp_path (MonoError *error)
7007 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7010 #ifndef PLATFORM_NO_DRIVEINFO
7011 ICALL_EXPORT MonoBoolean
7012 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7013 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7017 ULARGE_INTEGER wapi_free_bytes_avail;
7018 ULARGE_INTEGER wapi_total_number_of_bytes;
7019 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7021 *error = ERROR_SUCCESS;
7022 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7023 &wapi_total_number_of_free_bytes);
7026 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7027 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7028 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7030 *free_bytes_avail = 0;
7031 *total_number_of_bytes = 0;
7032 *total_number_of_free_bytes = 0;
7033 *error = GetLastError ();
7039 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7040 static inline guint32
7041 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7043 return GetDriveType (mono_string_chars (root_path_name));
7045 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7047 ICALL_EXPORT guint32
7048 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7050 return mono_icall_drive_info_get_drive_type (root_path_name);
7053 #endif /* PLATFORM_NO_DRIVEINFO */
7055 ICALL_EXPORT gpointer
7056 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7059 gpointer result = mono_compile_method_checked (method, &error);
7060 mono_error_set_pending_exception (&error);
7064 ICALL_EXPORT MonoString *
7065 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7070 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7072 mono_icall_make_platform_path (path);
7074 mcpath = mono_string_new (mono_domain_get (), path);
7080 /* this is an icall */
7082 get_bundled_app_config (void)
7085 const gchar *app_config;
7088 gchar *config_file_name, *config_file_path;
7089 gsize len, config_file_path_length, config_ext_length;
7092 domain = mono_domain_get ();
7093 file = domain->setup->configuration_file;
7094 if (!file || file->length == 0)
7097 // Retrieve config file and remove the extension
7098 config_file_name = mono_string_to_utf8_checked (file, &error);
7099 if (mono_error_set_pending_exception (&error))
7101 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7102 if (!config_file_path)
7103 config_file_path = config_file_name;
7105 config_file_path_length = strlen (config_file_path);
7106 config_ext_length = strlen (".config");
7107 if (config_file_path_length <= config_ext_length)
7110 len = config_file_path_length - config_ext_length;
7111 module = (gchar *)g_malloc0 (len + 1);
7112 memcpy (module, config_file_path, len);
7113 // Get the config file from the module name
7114 app_config = mono_config_string_for_assembly_file (module);
7117 if (config_file_name != config_file_path)
7118 g_free (config_file_name);
7119 g_free (config_file_path);
7124 return mono_string_new (mono_domain_get (), app_config);
7127 static MonoStringHandle
7128 get_bundled_machine_config (MonoError *error)
7130 const gchar *machine_config;
7132 machine_config = mono_get_machine_config ();
7134 if (!machine_config)
7135 return NULL_HANDLE_STRING;
7137 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7140 ICALL_EXPORT MonoStringHandle
7141 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7143 return get_bundled_machine_config (error);
7147 ICALL_EXPORT MonoStringHandle
7148 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7150 return get_bundled_machine_config (error);
7153 ICALL_EXPORT MonoStringHandle
7154 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7156 return get_bundled_machine_config (error);
7160 ICALL_EXPORT MonoString *
7161 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7166 path = g_path_get_dirname (mono_get_config_dir ());
7168 mono_icall_make_platform_path (path);
7170 ipath = mono_string_new (mono_domain_get (), path);
7176 ICALL_EXPORT gboolean
7177 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7179 mono_error_init (error);
7180 MonoPEResourceDataEntry *entry;
7183 if (!assembly || !result || !size)
7188 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7189 image = assm->image;
7190 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7194 *result = mono_image_rva_map (image, entry->rde_data_offset);
7199 *size = entry->rde_size;
7204 ICALL_EXPORT MonoBoolean
7205 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7207 return mono_is_debugger_attached ();
7210 ICALL_EXPORT MonoBoolean
7211 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7213 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7214 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7220 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7222 if (mono_get_runtime_callbacks ()->debug_log)
7223 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7228 mono_icall_write_windows_debug_string (MonoString *message)
7230 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7232 #endif /* !HOST_WIN32 */
7235 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7237 mono_icall_write_windows_debug_string (message);
7240 /* Only used for value types */
7241 ICALL_EXPORT MonoObjectHandle
7242 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionTypeHandle ref_type, MonoError *error)
7244 mono_error_init (error);
7245 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
7246 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
7247 MonoClass *klass = mono_class_from_mono_type (type);
7249 mono_class_init_checked (klass, error);
7253 if (mono_class_is_nullable (klass))
7254 /* No arguments -> null */
7257 return MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, klass, error));
7260 ICALL_EXPORT MonoReflectionMethod *
7261 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7263 MonoReflectionMethod *ret = NULL;
7266 MonoClass *klass, *parent;
7267 MonoGenericContext *generic_inst = NULL;
7268 MonoMethod *method = m->method;
7269 MonoMethod *result = NULL;
7272 if (method->klass == NULL)
7275 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7276 MONO_CLASS_IS_INTERFACE (method->klass) ||
7277 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7280 slot = mono_method_get_vtable_slot (method);
7284 klass = method->klass;
7285 if (mono_class_is_ginst (klass)) {
7286 generic_inst = mono_class_get_context (klass);
7287 klass = mono_class_get_generic_class (klass)->container_class;
7292 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7293 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7294 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7295 or klass is the generic container class and generic_inst is the instantiation.
7297 when we go to the parent, if the parent is an open constructed type, we need to
7298 replace the type parameters by the definitions from the generic_inst, and then take it
7299 apart again into the klass and the generic_inst.
7301 For cases like this:
7302 class C<T> : B<T, int> {
7303 public override void Foo () { ... }
7305 class B<U,V> : A<HashMap<U,V>> {
7306 public override void Foo () { ... }
7309 public virtual void Foo () { ... }
7312 if at each iteration the parent isn't open, we can skip inflating it. if at some
7313 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7316 MonoGenericContext *parent_inst = NULL;
7317 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7318 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7319 if (!mono_error_ok (&error)) {
7320 mono_error_set_pending_exception (&error);
7324 if (mono_class_is_ginst (parent)) {
7325 parent_inst = mono_class_get_context (parent);
7326 parent = mono_class_get_generic_class (parent)->container_class;
7329 mono_class_setup_vtable (parent);
7330 if (parent->vtable_size <= slot)
7333 generic_inst = parent_inst;
7336 klass = klass->parent;
7339 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7340 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7341 if (!mono_error_ok (&error)) {
7342 mono_error_set_pending_exception (&error);
7346 generic_inst = NULL;
7348 if (mono_class_is_ginst (klass)) {
7349 generic_inst = mono_class_get_context (klass);
7350 klass = mono_class_get_generic_class (klass)->container_class;
7356 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7357 if (!mono_error_ok (&error)) {
7358 mono_error_set_pending_exception (&error);
7363 if (klass == method->klass)
7366 /*This is possible if definition == FALSE.
7367 * Do it here to be really sure we don't read invalid memory.
7369 if (slot >= klass->vtable_size)
7372 mono_class_setup_vtable (klass);
7374 result = klass->vtable [slot];
7375 if (result == NULL) {
7376 /* It is an abstract method */
7377 gboolean found = FALSE;
7378 gpointer iter = NULL;
7379 while ((result = mono_class_get_methods (klass, &iter))) {
7380 if (result->slot == slot) {
7385 /* found might be FALSE if we looked in an abstract class
7386 * that doesn't override an abstract method of its
7388 * abstract class Base {
7389 * public abstract void Foo ();
7391 * abstract class Derived : Base { }
7392 * class Child : Derived {
7393 * public override void Foo () { }
7396 * if m was Child.Foo and we ask for the base method,
7397 * then we get here with klass == Derived and found == FALSE
7399 /* but it shouldn't be the case that if we're looking
7400 * for the definition and didn't find a result; the
7401 * loop above should've taken us as far as we could
7403 g_assert (!(definition && !found));
7408 g_assert (result != NULL);
7410 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7411 mono_error_set_pending_exception (&error);
7415 ICALL_EXPORT MonoString*
7416 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7418 MonoMethod *method = m->method;
7420 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7425 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7427 iter->sig = *(MonoMethodSignature**)argsp;
7429 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7430 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7433 /* FIXME: it's not documented what start is exactly... */
7437 iter->args = argsp + sizeof (gpointer);
7439 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7441 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7444 ICALL_EXPORT MonoTypedRef
7445 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7447 guint32 i, arg_size;
7451 i = iter->sig->sentinelpos + iter->next_arg;
7453 g_assert (i < iter->sig->param_count);
7455 res.type = iter->sig->params [i];
7456 res.klass = mono_class_from_mono_type (res.type);
7457 arg_size = mono_type_stack_size (res.type, &align);
7458 #if defined(__arm__) || defined(__mips__)
7459 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7461 res.value = iter->args;
7462 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7463 /* Values are stored as 8 byte register sized objects, but 'value'
7464 * is dereferenced as a pointer in other routines.
7466 res.value = (char*)res.value + 4;
7468 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7469 if (arg_size <= sizeof (gpointer)) {
7471 int padding = arg_size - mono_type_size (res.type, &dummy);
7472 res.value = (guint8*)res.value + padding;
7475 iter->args = (char*)iter->args + arg_size;
7478 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7483 ICALL_EXPORT MonoTypedRef
7484 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7486 guint32 i, arg_size;
7490 i = iter->sig->sentinelpos + iter->next_arg;
7492 g_assert (i < iter->sig->param_count);
7494 while (i < iter->sig->param_count) {
7495 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7497 res.type = iter->sig->params [i];
7498 res.klass = mono_class_from_mono_type (res.type);
7499 /* FIXME: endianess issue... */
7500 arg_size = mono_type_stack_size (res.type, &align);
7501 #if defined(__arm__) || defined(__mips__)
7502 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7504 res.value = iter->args;
7505 iter->args = (char*)iter->args + arg_size;
7507 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7510 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7518 ICALL_EXPORT MonoType*
7519 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7523 i = iter->sig->sentinelpos + iter->next_arg;
7525 g_assert (i < iter->sig->param_count);
7527 return iter->sig->params [i];
7530 ICALL_EXPORT MonoObject*
7531 mono_TypedReference_ToObject (MonoTypedRef* tref)
7534 MonoObject *result = NULL;
7535 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7536 MonoObject** objp = (MonoObject **)tref->value;
7540 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7541 mono_error_set_pending_exception (&error);
7545 ICALL_EXPORT MonoTypedRef
7546 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7549 MonoReflectionField *f;
7551 MonoType *ftype = NULL;
7555 memset (&res, 0, sizeof (res));
7558 g_assert (mono_array_length (fields) > 0);
7560 klass = target->vtable->klass;
7562 for (i = 0; i < mono_array_length (fields); ++i) {
7563 f = mono_array_get (fields, MonoReflectionField*, i);
7565 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7568 if (f->field->parent != klass) {
7569 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7573 p = (guint8*)target + f->field->offset;
7575 p += f->field->offset - sizeof (MonoObject);
7576 klass = mono_class_from_mono_type (f->field->type);
7577 ftype = f->field->type;
7581 res.klass = mono_class_from_mono_type (ftype);
7588 prelink_method (MonoMethod *method, MonoError *error)
7590 const char *exc_class, *exc_arg;
7592 mono_error_init (error);
7593 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7595 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7597 mono_error_set_exception_instance (error,
7598 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7601 /* create the wrapper, too? */
7605 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7609 prelink_method (method->method, &error);
7610 mono_error_set_pending_exception (&error);
7614 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7617 MonoClass *klass = mono_class_from_mono_type (type->type);
7619 gpointer iter = NULL;
7621 mono_class_init_checked (klass, &error);
7622 if (mono_error_set_pending_exception (&error))
7625 while ((m = mono_class_get_methods (klass, &iter))) {
7626 prelink_method (m, &error);
7627 if (mono_error_set_pending_exception (&error))
7632 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7634 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7635 gint32 const **exponents,
7636 gunichar2 const **digitLowerTable,
7637 gunichar2 const **digitUpperTable,
7638 gint64 const **tenPowersList,
7639 gint32 const **decHexDigits)
7641 *mantissas = Formatter_MantissaBitsTable;
7642 *exponents = Formatter_TensExponentTable;
7643 *digitLowerTable = Formatter_DigitLowerTable;
7644 *digitUpperTable = Formatter_DigitUpperTable;
7645 *tenPowersList = Formatter_TenPowersList;
7646 *decHexDigits = Formatter_DecHexDigits;
7650 add_modifier_to_array (MonoDomain *domain, MonoImage *image, MonoCustomMod *modifier, MonoArrayHandle dest, int dest_idx, MonoError *error)
7652 HANDLE_FUNCTION_ENTER ();
7653 mono_error_init (error);
7654 MonoClass *klass = mono_class_get_checked (image, modifier->token, error);
7658 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
7662 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rt);
7664 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
7668 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7669 * and avoid useless allocations.
7671 static MonoArrayHandle
7672 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7675 MonoDomain *domain = mono_domain_get ();
7677 mono_error_init (error);
7678 for (i = 0; i < type->num_mods; ++i) {
7679 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7683 return MONO_HANDLE_NEW (MonoArray, NULL);
7685 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
7689 for (i = 0; i < type->num_mods; ++i) {
7690 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7691 if (!add_modifier_to_array (domain, image, &type->modifiers[i], res, count , error))
7698 return MONO_HANDLE_NEW (MonoArray, NULL);
7701 ICALL_EXPORT MonoArrayHandle
7702 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameterHandle param, MonoBoolean optional, MonoError *error)
7704 mono_error_init (error);
7705 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
7706 MONO_HANDLE_GET (rt, param, ClassImpl);
7707 MonoType *type = MONO_HANDLE_GETVAL (rt, type);
7708 MonoObjectHandle member = MONO_HANDLE_NEW (MonoObject, NULL);
7709 MONO_HANDLE_GET (member, param, MemberImpl);
7710 MonoClass *member_class = mono_handle_class (member);
7711 MonoMethod *method = NULL;
7714 MonoMethodSignature *sig;
7716 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7717 method = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod, member), method);
7718 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7719 MonoProperty *prop = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionProperty, member), property);
7720 if (!(method = prop->get))
7724 char *type_name = mono_type_get_full_name (member_class);
7725 mono_error_set_not_supported (error, "Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7727 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7730 image = method->klass->image;
7731 pos = MONO_HANDLE_GETVAL (param, PositionImpl);
7732 sig = mono_method_signature (method);
7736 type = sig->params [pos];
7738 return type_array_from_modifiers (image, type, optional, error);
7742 get_property_type (MonoProperty *prop)
7744 MonoMethodSignature *sig;
7746 sig = mono_method_signature (prop->get);
7748 } else if (prop->set) {
7749 sig = mono_method_signature (prop->set);
7750 return sig->params [sig->param_count - 1];
7755 ICALL_EXPORT MonoArrayHandle
7756 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, MonoError *error)
7758 mono_error_init (error);
7759 MonoProperty *prop = MONO_HANDLE_GETVAL (property, property);
7760 MonoClass *klass = MONO_HANDLE_GETVAL (property, klass);
7761 MonoType *type = get_property_type (prop);
7762 MonoImage *image = klass->image;
7765 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7766 return type_array_from_modifiers (image, type, optional, error);
7770 *Construct a MonoType suited to be used to decode a constant blob object.
7772 * @type is the target type which will be constructed
7773 * @blob_type is the blob type, for example, that comes from the constant table
7774 * @real_type is the expected constructed type.
7777 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7779 type->type = blob_type;
7780 type->data.klass = NULL;
7781 if (blob_type == MONO_TYPE_CLASS)
7782 type->data.klass = mono_defaults.object_class;
7783 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7784 /* For enums, we need to use the base type */
7785 type->type = MONO_TYPE_VALUETYPE;
7786 type->data.klass = mono_class_from_mono_type (real_type);
7788 type->data.klass = mono_class_from_mono_type (real_type);
7791 ICALL_EXPORT MonoObject*
7792 property_info_get_default_value (MonoReflectionProperty *property)
7796 MonoProperty *prop = property->property;
7797 MonoType *type = get_property_type (prop);
7798 MonoDomain *domain = mono_object_domain (property);
7799 MonoTypeEnum def_type;
7800 const char *def_value;
7803 mono_class_init (prop->parent);
7805 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7806 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7810 def_value = mono_class_get_property_default_value (prop, &def_type);
7812 mono_type_from_blob_type (&blob_type, def_type, type);
7813 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7815 mono_error_set_pending_exception (&error);
7819 ICALL_EXPORT MonoBoolean
7820 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7823 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7824 MonoCustomAttrInfo *cinfo;
7827 mono_class_init_checked (attr_class, &error);
7828 if (mono_error_set_pending_exception (&error))
7831 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7832 if (!is_ok (&error)) {
7833 mono_error_set_pending_exception (&error);
7838 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7840 mono_custom_attrs_free (cinfo);
7844 ICALL_EXPORT MonoArray*
7845 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7847 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7852 mono_class_init_checked (attr_class, &error);
7853 if (mono_error_set_pending_exception (&error))
7857 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7858 if (!mono_error_ok (&error)) {
7859 mono_error_set_pending_exception (&error);
7866 ICALL_EXPORT MonoArray*
7867 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7871 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7872 mono_error_set_pending_exception (&error);
7877 ICALL_EXPORT MonoStringHandle
7878 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7881 MonoStringHandle display_name;
7883 mono_error_init (error);
7884 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7885 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7887 return display_name;
7891 static inline gint32
7892 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7894 return WAIT_TIMEOUT;
7896 #endif /* !HOST_WIN32 */
7899 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7901 return mono_icall_wait_for_input_idle (handle, milliseconds);
7905 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7907 return mono_process_current_pid ();
7910 ICALL_EXPORT MonoBoolean
7911 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7923 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7925 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7929 ICALL_EXPORT MonoObject*
7930 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7932 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7937 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7939 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7943 ICALL_EXPORT MonoObject*
7944 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7946 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7950 ICALL_EXPORT MonoBoolean
7951 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7953 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7958 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7960 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7964 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7966 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7971 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7973 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7977 ICALL_EXPORT mono_unichar2*
7978 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7980 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7987 #ifndef DISABLE_ICALL_TABLES
7989 #define ICALL_TYPE(id,name,first)
7990 #define ICALL(id,name,func) Icall_ ## id,
7991 #define HANDLES(inner) inner
7994 #include "metadata/icall-def.h"
8000 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8001 #define ICALL(id,name,func)
8003 #define HANDLES(inner) inner
8005 #include "metadata/icall-def.h"
8011 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8012 #define ICALL(id,name,func)
8014 #define HANDLES(inner) inner
8016 guint16 first_icall;
8019 static const IcallTypeDesc
8020 icall_type_descs [] = {
8021 #include "metadata/icall-def.h"
8025 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8028 #define HANDLES(inner) inner
8030 #define ICALL_TYPE(id,name,first)
8033 #ifdef HAVE_ARRAY_ELEM_INIT
8034 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8035 #define MSGSTRFIELD1(line) str##line
8037 static const struct msgstrtn_t {
8038 #define ICALL(id,name,func)
8040 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8041 #include "metadata/icall-def.h"
8043 } icall_type_names_str = {
8044 #define ICALL_TYPE(id,name,first) (name),
8045 #include "metadata/icall-def.h"
8048 static const guint16 icall_type_names_idx [] = {
8049 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8050 #include "metadata/icall-def.h"
8053 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8055 static const struct msgstr_t {
8057 #define ICALL_TYPE(id,name,first)
8058 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8059 #include "metadata/icall-def.h"
8061 } icall_names_str = {
8062 #define ICALL(id,name,func) (name),
8063 #include "metadata/icall-def.h"
8066 static const guint16 icall_names_idx [] = {
8067 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8068 #include "metadata/icall-def.h"
8071 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8077 #define ICALL_TYPE(id,name,first) name,
8078 #define ICALL(id,name,func)
8079 static const char* const
8080 icall_type_names [] = {
8081 #include "metadata/icall-def.h"
8085 #define icall_type_name_get(id) (icall_type_names [(id)])
8089 #define ICALL_TYPE(id,name,first)
8090 #define ICALL(id,name,func) name,
8091 static const char* const
8093 #include "metadata/icall-def.h"
8096 #define icall_name_get(id) icall_names [(id)]
8098 #endif /* !HAVE_ARRAY_ELEM_INIT */
8101 #define HANDLES(inner) inner
8104 #define ICALL_TYPE(id,name,first)
8105 #define ICALL(id,name,func) func,
8106 static const gconstpointer
8107 icall_functions [] = {
8108 #include "metadata/icall-def.h"
8112 #ifdef ENABLE_ICALL_SYMBOL_MAP
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_symbols [] = {
8121 #include "metadata/icall-def.h"
8128 #define ICALL_TYPE(id,name,first)
8129 #define ICALL(id,name,func) 0,
8131 #define HANDLES(inner) 1,
8133 icall_uses_handles [] = {
8134 #include "metadata/icall-def.h"
8139 #endif /* DISABLE_ICALL_TABLES */
8141 static mono_mutex_t icall_mutex;
8142 static GHashTable *icall_hash = NULL;
8143 static GHashTable *jit_icall_hash_name = NULL;
8144 static GHashTable *jit_icall_hash_addr = NULL;
8147 mono_icall_init (void)
8149 #ifndef DISABLE_ICALL_TABLES
8152 /* check that tables are sorted: disable in release */
8155 const char *prev_class = NULL;
8156 const char *prev_method;
8158 for (i = 0; i < Icall_type_num; ++i) {
8159 const IcallTypeDesc *desc;
8162 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8163 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8164 prev_class = icall_type_name_get (i);
8165 desc = &icall_type_descs [i];
8166 num_icalls = icall_desc_num_icalls (desc);
8167 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8168 for (j = 0; j < num_icalls; ++j) {
8169 const char *methodn = icall_name_get (desc->first_icall + j);
8170 if (prev_method && strcmp (prev_method, methodn) >= 0)
8171 g_print ("method %s should come before method %s\n", methodn, prev_method);
8172 prev_method = methodn;
8178 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8179 mono_os_mutex_init (&icall_mutex);
8183 mono_icall_lock (void)
8185 mono_locks_os_acquire (&icall_mutex, IcallLock);
8189 mono_icall_unlock (void)
8191 mono_locks_os_release (&icall_mutex, IcallLock);
8195 mono_icall_cleanup (void)
8197 g_hash_table_destroy (icall_hash);
8198 g_hash_table_destroy (jit_icall_hash_name);
8199 g_hash_table_destroy (jit_icall_hash_addr);
8200 mono_os_mutex_destroy (&icall_mutex);
8204 * mono_add_internal_call:
8205 * @name: method specification to surface to the managed world
8206 * @method: pointer to a C method to invoke when the method is called
8208 * This method surfaces the C function pointed by @method as a method
8209 * that has been surfaced in managed code with the method specified in
8210 * @name as an internal call.
8212 * Internal calls are surfaced to all app domains loaded and they are
8213 * accessibly by a type with the specified name.
8215 * You must provide a fully qualified type name, that is namespaces
8216 * and type name, followed by a colon and the method name, with an
8217 * optional signature to bind.
8219 * For example, the following are all valid declarations:
8221 * "MyApp.Services.ScriptService:Accelerate"
8222 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8224 * You use method parameters in cases where there might be more than
8225 * one surface method to managed code. That way you can register different
8226 * internal calls for different method overloads.
8228 * The internal calls are invoked with no marshalling. This means that .NET
8229 * types like System.String are exposed as `MonoString *` parameters. This is
8230 * different than the way that strings are surfaced in P/Invoke.
8232 * For more information on how the parameters are marshalled, see the
8233 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8236 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8237 * reference for more information on the format of method descriptions.
8240 mono_add_internal_call (const char *name, gconstpointer method)
8244 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8246 mono_icall_unlock ();
8249 #ifndef DISABLE_ICALL_TABLES
8251 #ifdef HAVE_ARRAY_ELEM_INIT
8253 compare_method_imap (const void *key, const void *elem)
8255 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8256 return strcmp (key, method_name);
8260 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8262 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);
8265 return (nameslot - &icall_names_idx [0]);
8269 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8271 gsize slotnum = find_slot_icall (imap, name);
8274 return (gboolean)icall_uses_handles [slotnum];
8278 find_method_icall (const IcallTypeDesc *imap, const char *name)
8280 gsize slotnum = find_slot_icall (imap, name);
8283 return (gpointer)icall_functions [slotnum];
8287 compare_class_imap (const void *key, const void *elem)
8289 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8290 return strcmp (key, class_name);
8293 static const IcallTypeDesc*
8294 find_class_icalls (const char *name)
8296 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);
8299 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8302 #else /* HAVE_ARRAY_ELEM_INIT */
8305 compare_method_imap (const void *key, const void *elem)
8307 const char** method_name = (const char**)elem;
8308 return strcmp (key, *method_name);
8312 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8314 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8317 return nameslot - icall_names;
8321 find_method_icall (const IcallTypeDesc *imap, const char *name)
8323 gsize slotnum = find_slot_icall (imap, name);
8326 return (gpointer)icall_functions [slotnum];
8330 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8332 gsize slotnum = find_slot_icall (imap, name);
8335 return (gboolean)icall_uses_handles [slotnum];
8339 compare_class_imap (const void *key, const void *elem)
8341 const char** class_name = (const char**)elem;
8342 return strcmp (key, *class_name);
8345 static const IcallTypeDesc*
8346 find_class_icalls (const char *name)
8348 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8351 return &icall_type_descs [nameslot - icall_type_names];
8354 #endif /* HAVE_ARRAY_ELEM_INIT */
8356 #endif /* DISABLE_ICALL_TABLES */
8359 * we should probably export this as an helper (handle nested types).
8360 * Returns the number of chars written in buf.
8363 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8365 int nspacelen, cnamelen;
8366 nspacelen = strlen (klass->name_space);
8367 cnamelen = strlen (klass->name);
8368 if (nspacelen + cnamelen + 2 > bufsize)
8371 memcpy (buf, klass->name_space, nspacelen);
8372 buf [nspacelen ++] = '.';
8374 memcpy (buf + nspacelen, klass->name, cnamelen);
8375 buf [nspacelen + cnamelen] = 0;
8376 return nspacelen + cnamelen;
8379 #ifdef DISABLE_ICALL_TABLES
8381 no_icall_table (void)
8383 g_assert_not_reached ();
8388 * mono_lookup_internal_call_full:
8389 * @method: the method to look up
8390 * @uses_handles: out argument if method needs handles around managed objects.
8392 * Returns a pointer to the icall code for the given method. If
8393 * uses_handles is not NULL, it will be set to TRUE if the method
8394 * needs managed objects wrapped using the infrastructure in handle.h
8396 * If the method is not found, warns and returns NULL.
8399 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8404 int typelen = 0, mlen, siglen;
8406 #ifndef DISABLE_ICALL_TABLES
8407 const IcallTypeDesc *imap = NULL;
8410 g_assert (method != NULL);
8412 if (method->is_inflated)
8413 method = ((MonoMethodInflated *) method)->declaring;
8415 if (method->klass->nested_in) {
8416 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8420 mname [pos++] = '/';
8423 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8429 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8434 #ifndef DISABLE_ICALL_TABLES
8435 imap = find_class_icalls (mname);
8438 mname [typelen] = ':';
8439 mname [typelen + 1] = ':';
8441 mlen = strlen (method->name);
8442 memcpy (mname + typelen + 2, method->name, mlen);
8443 sigstart = mname + typelen + 2 + mlen;
8446 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8447 siglen = strlen (tmpsig);
8448 if (typelen + mlen + siglen + 6 > sizeof (mname))
8451 memcpy (sigstart + 1, tmpsig, siglen);
8452 sigstart [siglen + 1] = ')';
8453 sigstart [siglen + 2] = 0;
8458 res = g_hash_table_lookup (icall_hash, mname);
8461 *uses_handles = FALSE;
8462 mono_icall_unlock ();;
8465 /* try without signature */
8467 res = g_hash_table_lookup (icall_hash, mname);
8470 *uses_handles = FALSE;
8471 mono_icall_unlock ();
8475 #ifdef DISABLE_ICALL_TABLES
8476 mono_icall_unlock ();
8477 /* Fail only when the result is actually used */
8478 /* mono_marshal_get_native_wrapper () depends on this */
8479 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8480 return ves_icall_System_String_ctor_RedirectToCreateString;
8482 return no_icall_table;
8484 /* it wasn't found in the static call tables */
8487 *uses_handles = FALSE;
8488 mono_icall_unlock ();
8491 res = find_method_icall (imap, sigstart - mlen);
8494 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8495 mono_icall_unlock ();
8498 /* try _with_ signature */
8500 res = find_method_icall (imap, sigstart - mlen);
8503 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8504 mono_icall_unlock ();
8508 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8509 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8510 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8511 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8512 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");
8513 g_print ("If you see other errors or faults after this message they are probably related\n");
8514 g_print ("and you need to fix your mono install first.\n");
8516 mono_icall_unlock ();
8523 mono_lookup_internal_call (MonoMethod *method)
8525 return mono_lookup_internal_call_full (method, NULL);
8528 #ifdef ENABLE_ICALL_SYMBOL_MAP
8530 func_cmp (gconstpointer key, gconstpointer p)
8532 return (gsize)key - (gsize)*(gsize*)p;
8537 * mono_lookup_icall_symbol:
8539 * Given the icall METHOD, returns its C symbol.
8542 mono_lookup_icall_symbol (MonoMethod *m)
8544 #ifdef DISABLE_ICALL_TABLES
8545 g_assert_not_reached ();
8548 #ifdef ENABLE_ICALL_SYMBOL_MAP
8552 static gconstpointer *functions_sorted;
8553 static const char**symbols_sorted;
8554 static gboolean inited;
8559 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8560 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8561 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8562 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8563 /* Bubble sort the two arrays */
8567 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8568 if (functions_sorted [i] > functions_sorted [i + 1]) {
8571 tmp = functions_sorted [i];
8572 functions_sorted [i] = functions_sorted [i + 1];
8573 functions_sorted [i + 1] = tmp;
8574 tmp = symbols_sorted [i];
8575 symbols_sorted [i] = symbols_sorted [i + 1];
8576 symbols_sorted [i + 1] = tmp;
8583 func = mono_lookup_internal_call (m);
8586 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8590 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8592 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8593 g_assert_not_reached ();
8600 type_from_typename (char *type_name)
8602 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8604 if (!strcmp (type_name, "int"))
8605 klass = mono_defaults.int_class;
8606 else if (!strcmp (type_name, "ptr"))
8607 klass = mono_defaults.int_class;
8608 else if (!strcmp (type_name, "void"))
8609 klass = mono_defaults.void_class;
8610 else if (!strcmp (type_name, "int32"))
8611 klass = mono_defaults.int32_class;
8612 else if (!strcmp (type_name, "uint32"))
8613 klass = mono_defaults.uint32_class;
8614 else if (!strcmp (type_name, "int8"))
8615 klass = mono_defaults.sbyte_class;
8616 else if (!strcmp (type_name, "uint8"))
8617 klass = mono_defaults.byte_class;
8618 else if (!strcmp (type_name, "int16"))
8619 klass = mono_defaults.int16_class;
8620 else if (!strcmp (type_name, "uint16"))
8621 klass = mono_defaults.uint16_class;
8622 else if (!strcmp (type_name, "long"))
8623 klass = mono_defaults.int64_class;
8624 else if (!strcmp (type_name, "ulong"))
8625 klass = mono_defaults.uint64_class;
8626 else if (!strcmp (type_name, "float"))
8627 klass = mono_defaults.single_class;
8628 else if (!strcmp (type_name, "double"))
8629 klass = mono_defaults.double_class;
8630 else if (!strcmp (type_name, "object"))
8631 klass = mono_defaults.object_class;
8632 else if (!strcmp (type_name, "obj"))
8633 klass = mono_defaults.object_class;
8634 else if (!strcmp (type_name, "string"))
8635 klass = mono_defaults.string_class;
8636 else if (!strcmp (type_name, "bool"))
8637 klass = mono_defaults.boolean_class;
8638 else if (!strcmp (type_name, "boolean"))
8639 klass = mono_defaults.boolean_class;
8641 g_error ("%s", type_name);
8642 g_assert_not_reached ();
8644 return &klass->byval_arg;
8648 * LOCKING: Take the corlib image lock.
8650 MonoMethodSignature*
8651 mono_create_icall_signature (const char *sigstr)
8656 MonoMethodSignature *res, *res2;
8657 MonoImage *corlib = mono_defaults.corlib;
8659 mono_image_lock (corlib);
8660 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8661 mono_image_unlock (corlib);
8666 parts = g_strsplit (sigstr, " ", 256);
8675 res = mono_metadata_signature_alloc (corlib, len - 1);
8680 * Under windows, the default pinvoke calling convention is STDCALL but
8683 res->call_convention = MONO_CALL_C;
8686 res->ret = type_from_typename (parts [0]);
8687 for (i = 1; i < len; ++i) {
8688 res->params [i - 1] = type_from_typename (parts [i]);
8693 mono_image_lock (corlib);
8694 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8696 res = res2; /*Value is allocated in the image pool*/
8698 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8699 mono_image_unlock (corlib);
8705 mono_find_jit_icall_by_name (const char *name)
8707 MonoJitICallInfo *info;
8708 g_assert (jit_icall_hash_name);
8711 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8712 mono_icall_unlock ();
8717 mono_find_jit_icall_by_addr (gconstpointer addr)
8719 MonoJitICallInfo *info;
8720 g_assert (jit_icall_hash_addr);
8723 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8724 mono_icall_unlock ();
8730 * mono_get_jit_icall_info:
8732 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8733 * caller should access it while holding the icall lock.
8736 mono_get_jit_icall_info (void)
8738 return jit_icall_hash_name;
8742 * mono_lookup_jit_icall_symbol:
8744 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8747 mono_lookup_jit_icall_symbol (const char *name)
8749 MonoJitICallInfo *info;
8750 const char *res = NULL;
8753 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8755 res = info->c_symbol;
8756 mono_icall_unlock ();
8761 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8764 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8765 mono_icall_unlock ();
8769 * 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
8770 * icalls without wrappers in some cases.
8773 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8775 MonoJitICallInfo *info;
8782 if (!jit_icall_hash_name) {
8783 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8784 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8787 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8788 g_warning ("jit icall already defined \"%s\"\n", name);
8789 g_assert_not_reached ();
8792 info = g_new0 (MonoJitICallInfo, 1);
8797 info->c_symbol = c_symbol;
8798 info->no_raise = no_raise;
8801 info->wrapper = func;
8803 info->wrapper = NULL;
8806 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8807 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8809 mono_icall_unlock ();
8814 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8816 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);