5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool-ms.h>
40 #include <mono/metadata/threadpool-ms-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/domain-internals.h>
56 #include <mono/metadata/metadata-internals.h>
57 #include <mono/metadata/class-internals.h>
58 #include <mono/metadata/reflection-internals.h>
59 #include <mono/metadata/marshal.h>
60 #include <mono/metadata/gc-internals.h>
61 #include <mono/metadata/mono-gc.h>
62 #include <mono/metadata/rand.h>
63 #include <mono/metadata/sysmath.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
846 MonoClass *klass = array->obj.vtable->klass;
847 guint32 size = mono_array_element_size (klass);
848 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
850 const char *field_data;
852 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
853 MonoException *exc = mono_get_exception_argument("array",
854 "Cannot initialize array of non-primitive type.");
855 mono_set_pending_exception (exc);
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 MonoException *exc = mono_get_exception_argument("field_handle",
861 "Field doesn't have an RVA");
862 mono_set_pending_exception (exc);
866 size *= array->max_length;
867 field_data = mono_field_get_data (field_handle);
869 if (size > mono_type_size (field_handle->type, &align)) {
870 MonoException *exc = mono_get_exception_argument("field_handle",
871 "Field not large enough to fill array");
872 mono_set_pending_exception (exc);
876 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
878 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
879 guint ## n *src = (guint ## n *) field_data; \
881 nEnt = (size / sizeof(guint ## n)); \
883 for (i = 0; i < nEnt; i++) { \
884 data[i] = read ## n (&src[i]); \
888 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
890 switch (type->type) {
907 memcpy (mono_array_addr (array, char, 0), field_data, size);
911 memcpy (mono_array_addr (array, char, 0), field_data, size);
916 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
918 return offsetof (MonoString, chars);
921 ICALL_EXPORT MonoObject *
922 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
924 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
928 MonoObject *ret = mono_object_clone_checked (obj, &error);
929 mono_error_set_pending_exception (&error);
936 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
942 MONO_CHECK_ARG_NULL (handle,);
944 klass = mono_class_from_mono_type (handle);
945 MONO_CHECK_ARG (handle, klass,);
947 if (klass->generic_container)
950 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
951 if (!is_ok (&error)) {
952 mono_error_set_pending_exception (&error);
956 /* This will call the type constructor */
957 if (!mono_runtime_class_init_full (vtable, &error))
958 mono_error_set_pending_exception (&error);
962 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
966 mono_image_check_for_module_cctor (image);
967 if (image->has_module_cctor) {
968 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
969 if (!mono_error_ok (&error)) {
970 mono_error_set_pending_exception (&error);
973 /*It's fine to raise the exception here*/
974 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
975 if (!is_ok (&error)) {
976 mono_error_set_pending_exception (&error);
979 if (!mono_runtime_class_init_full (vtable, &error))
980 mono_error_set_pending_exception (&error);
984 ICALL_EXPORT MonoBoolean
985 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
987 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
988 // It does not work on win32
994 MonoInternalThread *thread;
996 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
997 /* if we have no info we are optimistic and assume there is enough room */
1001 thread = mono_thread_internal_current ();
1002 // .net seems to check that at least 50% of stack is available
1003 min_size = thread->stack_size / 2;
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionType *
1216 ves_icall_System_Object_GetType (MonoObject *obj)
1219 MonoReflectionType *ret;
1220 #ifndef DISABLE_REMOTING
1221 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1222 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1225 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1227 mono_error_set_pending_exception (&error);
1232 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1234 MonoMethod **dest = (MonoMethod **)data;
1236 /* skip unmanaged frames */
1241 if (!strcmp (m->klass->name_space, "System.Reflection"))
1250 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1252 MonoMethod **dest = (MonoMethod **)data;
1254 /* skip unmanaged frames */
1258 if (m->wrapper_type != MONO_WRAPPER_NONE)
1266 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1277 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1279 MonoMethod **dest = (MonoMethod **)data;
1281 /* skip unmanaged frames */
1285 if (m->wrapper_type != MONO_WRAPPER_NONE)
1293 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1294 || (!strcmp (m->klass->name_space, "System"))))
1304 static MonoReflectionType *
1305 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoError *error)
1307 MonoMethod *m, *dest;
1309 MonoType *type = NULL;
1310 MonoAssembly *assembly = NULL;
1311 gboolean type_resolve = FALSE;
1312 MonoImage *rootimage = NULL;
1314 mono_error_init (error);
1317 * We must compute the calling assembly as type loading must happen under a metadata context.
1318 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1319 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1321 m = mono_method_get_last_managed ();
1323 if (m && m->klass->image != mono_defaults.corlib) {
1324 /* Happens with inlining */
1326 /* Ugly hack: type_from_parsed_name is called from
1327 * System.Type.internal_from_name, which is called most
1328 * directly from System.Type.GetType(string,bool,bool) but
1329 * also indirectly from places such as
1330 * System.Type.GetType(string,func,func) (via
1331 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1332 * so we need to skip over all of those to find the true caller.
1334 * It would be nice if we had stack marks.
1336 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1342 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1343 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1344 * to crash. This only seems to happen in some strange remoting
1345 * scenarios and I was unable to figure out what's happening there.
1346 * Dec 10, 2005 - Martin.
1350 assembly = dest->klass->image->assembly;
1351 type_resolve = TRUE;
1352 rootimage = assembly->image;
1354 g_warning (G_STRLOC);
1357 if (info->assembly.name)
1358 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1361 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1362 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1363 return_val_if_nok (error, NULL);
1367 // Say we're looking for System.Generic.Dict<int, Local>
1368 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1369 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1370 // is messed up when we go to construct the Local as the type arg...
1372 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1373 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1374 if (!info->assembly.name && !type) {
1376 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1377 return_val_if_nok (error, NULL);
1379 if (assembly && !type && type_resolve) {
1380 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1381 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1382 return_val_if_nok (error, NULL);
1388 return mono_type_get_object_checked (mono_domain_get (), type, error);
1391 ICALL_EXPORT MonoReflectionType*
1392 ves_icall_System_Type_internal_from_name (MonoString *name,
1393 MonoBoolean throwOnError,
1394 MonoBoolean ignoreCase)
1397 MonoTypeNameParse info;
1398 MonoReflectionType *type = NULL;
1401 char *str = mono_string_to_utf8_checked (name, &error);
1402 if (!is_ok (&error))
1405 parsedOk = mono_reflection_parse_type (str, &info);
1407 /* mono_reflection_parse_type() mangles the string */
1409 mono_reflection_free_type_info (&info);
1411 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1415 type = type_from_parsed_name (&info, ignoreCase, &error);
1417 mono_reflection_free_type_info (&info);
1419 if (!is_ok (&error))
1424 mono_error_set_type_load_name (&error, g_strdup (str), g_strdup (""), "");
1431 if (!is_ok (&error)) {
1433 mono_error_set_pending_exception (&error);
1435 mono_error_cleanup (&error);
1443 ICALL_EXPORT MonoReflectionType*
1444 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1447 MonoReflectionType *ret;
1448 MonoDomain *domain = mono_domain_get ();
1450 ret = mono_type_get_object_checked (domain, handle, &error);
1451 mono_error_set_pending_exception (&error);
1456 ICALL_EXPORT MonoType*
1457 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1459 return mono_class_get_type (klass);
1463 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1465 g_ptr_array_free (ptr_array, TRUE);
1469 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1475 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1478 char *res = mono_string_to_utf8_checked (s, &error);
1479 mono_error_set_pending_exception (&error);
1483 /* System.TypeCode */
1502 TYPECODE_STRING = 18
1505 ICALL_EXPORT guint32
1506 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1508 int t = type->type->type;
1510 if (type->type->byref)
1511 return TYPECODE_OBJECT;
1515 case MONO_TYPE_VOID:
1516 return TYPECODE_OBJECT;
1517 case MONO_TYPE_BOOLEAN:
1518 return TYPECODE_BOOLEAN;
1520 return TYPECODE_BYTE;
1522 return TYPECODE_SBYTE;
1524 return TYPECODE_UINT16;
1526 return TYPECODE_INT16;
1527 case MONO_TYPE_CHAR:
1528 return TYPECODE_CHAR;
1532 return TYPECODE_OBJECT;
1534 return TYPECODE_UINT32;
1536 return TYPECODE_INT32;
1538 return TYPECODE_UINT64;
1540 return TYPECODE_INT64;
1542 return TYPECODE_SINGLE;
1544 return TYPECODE_DOUBLE;
1545 case MONO_TYPE_VALUETYPE: {
1546 MonoClass *klass = type->type->data.klass;
1548 if (klass->enumtype) {
1549 t = mono_class_enum_basetype (klass)->type;
1551 } else if (mono_is_corlib_image (klass->image)) {
1552 if (strcmp (klass->name_space, "System") == 0) {
1553 if (strcmp (klass->name, "Decimal") == 0)
1554 return TYPECODE_DECIMAL;
1555 else if (strcmp (klass->name, "DateTime") == 0)
1556 return TYPECODE_DATETIME;
1559 return TYPECODE_OBJECT;
1561 case MONO_TYPE_STRING:
1562 return TYPECODE_STRING;
1563 case MONO_TYPE_SZARRAY:
1564 case MONO_TYPE_ARRAY:
1565 case MONO_TYPE_OBJECT:
1567 case MONO_TYPE_MVAR:
1568 case MONO_TYPE_TYPEDBYREF:
1569 return TYPECODE_OBJECT;
1570 case MONO_TYPE_CLASS:
1572 MonoClass *klass = type->type->data.klass;
1573 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1574 if (strcmp (klass->name, "DBNull") == 0)
1575 return TYPECODE_DBNULL;
1578 return TYPECODE_OBJECT;
1579 case MONO_TYPE_GENERICINST:
1580 return TYPECODE_OBJECT;
1582 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1588 mono_type_is_primitive (MonoType *type)
1590 return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
1591 type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
1595 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1597 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1598 return mono_class_enum_basetype (type->data.klass);
1599 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1600 return mono_class_enum_basetype (type->data.generic_class->container_class);
1604 ICALL_EXPORT guint32
1605 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1610 g_assert (type != NULL);
1612 klass = mono_class_from_mono_type (type->type);
1613 klassc = mono_class_from_mono_type (c->type);
1615 if (type->type->byref ^ c->type->byref)
1618 if (type->type->byref) {
1619 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1620 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1622 klass = mono_class_from_mono_type (t);
1623 klassc = mono_class_from_mono_type (ot);
1625 if (mono_type_is_primitive (t)) {
1626 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1627 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1628 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1629 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1630 return t->type == ot->type;
1632 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1635 if (klass->valuetype)
1636 return klass == klassc;
1637 return klass->valuetype == klassc->valuetype;
1640 return mono_class_is_assignable_from (klass, klassc);
1643 ICALL_EXPORT guint32
1644 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1647 MonoClass *klass = mono_class_from_mono_type (type->type);
1648 mono_class_init_checked (klass, &error);
1649 if (!is_ok (&error)) {
1650 mono_error_set_pending_exception (&error);
1653 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1654 mono_error_set_pending_exception (&error);
1658 ICALL_EXPORT guint32
1659 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1661 MonoClass *klass = mono_class_from_mono_type (type->type);
1662 return klass->flags;
1665 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1666 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1669 MonoClass *klass = field->field->parent;
1670 MonoMarshalType *info;
1674 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1675 if (klass->generic_container ||
1676 (gklass && gklass->context.class_inst->is_open))
1679 ftype = mono_field_get_type (field->field);
1680 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1683 info = mono_marshal_load_type_info (klass);
1685 for (i = 0; i < info->num_fields; ++i) {
1686 if (info->fields [i].field == field->field) {
1687 if (!info->fields [i].mspec)
1690 MonoReflectionMarshalAsAttribute* obj;
1691 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1692 if (!mono_error_ok (&error))
1693 mono_error_set_pending_exception (&error);
1702 ICALL_EXPORT MonoReflectionField*
1703 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1706 gboolean found = FALSE;
1712 klass = handle->parent;
1714 klass = mono_class_from_mono_type (type);
1716 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1719 /* The managed code will throw the exception */
1723 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1724 mono_error_set_pending_exception (&error);
1728 ICALL_EXPORT MonoReflectionEvent*
1729 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1737 klass = handle->parent;
1739 klass = mono_class_from_mono_type (type);
1741 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1743 /* Managed code will throw an exception */
1747 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1748 mono_error_set_pending_exception (&error);
1753 ICALL_EXPORT MonoReflectionProperty*
1754 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1762 klass = handle->parent;
1764 klass = mono_class_from_mono_type (type);
1766 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1768 /* Managed code will throw an exception */
1772 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1773 mono_error_set_pending_exception (&error);
1777 ICALL_EXPORT MonoArray*
1778 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1781 MonoType *type = mono_field_get_type_checked (field->field, &error);
1784 if (!mono_error_ok (&error)) {
1785 mono_error_set_pending_exception (&error);
1789 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1790 mono_error_set_pending_exception (&error);
1795 vell_icall_get_method_attributes (MonoMethod *method)
1797 return method->flags;
1801 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1804 MonoReflectionType *rt;
1805 MonoDomain *domain = mono_domain_get ();
1806 MonoMethodSignature* sig;
1808 sig = mono_method_signature_checked (method, &error);
1809 if (!mono_error_ok (&error)) {
1810 mono_error_set_pending_exception (&error);
1814 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1815 if (!mono_error_ok (&error)) {
1816 mono_error_set_pending_exception (&error);
1820 MONO_STRUCT_SETREF (info, parent, rt);
1822 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1823 if (!mono_error_ok (&error)) {
1824 mono_error_set_pending_exception (&error);
1828 MONO_STRUCT_SETREF (info, ret, rt);
1830 info->attrs = method->flags;
1831 info->implattrs = method->iflags;
1832 if (sig->call_convention == MONO_CALL_DEFAULT)
1833 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1835 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1840 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1843 ICALL_EXPORT MonoArray*
1844 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1847 MonoDomain *domain = mono_domain_get ();
1849 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1850 mono_error_set_pending_exception (&error);
1854 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1855 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1858 MonoDomain *domain = mono_domain_get ();
1859 MonoReflectionMarshalAsAttribute* res = NULL;
1860 MonoMarshalSpec **mspecs;
1863 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1864 mono_method_get_marshal_info (method, mspecs);
1867 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1868 if (!mono_error_ok (&error)) {
1869 mono_error_set_pending_exception (&error);
1874 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1876 mono_metadata_free_marshal_spec (mspecs [i]);
1883 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1885 MonoClass *parent = field->field->parent;
1886 mono_class_setup_fields (parent);
1888 return field->field->offset - sizeof (MonoObject);
1891 ICALL_EXPORT MonoReflectionType*
1892 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1895 MonoReflectionType *ret;
1898 parent = declaring? field->field->parent: field->klass;
1900 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1901 mono_error_set_pending_exception (&error);
1907 ICALL_EXPORT MonoObject *
1908 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1911 MonoClass *fklass = field->klass;
1912 MonoClassField *cf = field->field;
1913 MonoDomain *domain = mono_object_domain (field);
1915 if (fklass->image->assembly->ref_only) {
1916 mono_set_pending_exception (mono_get_exception_invalid_operation (
1917 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1921 if (mono_security_core_clr_enabled () &&
1922 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1923 mono_error_set_pending_exception (&error);
1927 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1928 mono_error_set_pending_exception (&error);
1933 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1936 MonoClassField *cf = field->field;
1940 if (field->klass->image->assembly->ref_only) {
1941 mono_set_pending_exception (mono_get_exception_invalid_operation (
1942 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1946 if (mono_security_core_clr_enabled () &&
1947 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1948 mono_error_set_pending_exception (&error);
1952 type = mono_field_get_type_checked (cf, &error);
1953 if (!mono_error_ok (&error)) {
1954 mono_error_set_pending_exception (&error);
1958 v = (gchar *) value;
1960 switch (type->type) {
1963 case MONO_TYPE_BOOLEAN:
1966 case MONO_TYPE_CHAR:
1975 case MONO_TYPE_VALUETYPE:
1978 v += sizeof (MonoObject);
1980 case MONO_TYPE_STRING:
1981 case MONO_TYPE_OBJECT:
1982 case MONO_TYPE_CLASS:
1983 case MONO_TYPE_ARRAY:
1984 case MONO_TYPE_SZARRAY:
1987 case MONO_TYPE_GENERICINST: {
1988 MonoGenericClass *gclass = type->data.generic_class;
1989 g_assert (!gclass->context.class_inst->is_open);
1991 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1992 MonoClass *nklass = mono_class_from_mono_type (type);
1993 MonoObject *nullable;
1996 * Convert the boxed vtype into a Nullable structure.
1997 * This is complicated by the fact that Nullables have
1998 * a variable structure.
2000 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2001 if (!mono_error_ok (&error)) {
2002 mono_error_set_pending_exception (&error);
2006 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2008 v = (gchar *)mono_object_unbox (nullable);
2011 if (gclass->container_class->valuetype && (v != NULL))
2012 v += sizeof (MonoObject);
2016 g_error ("type 0x%x not handled in "
2017 "ves_icall_FieldInfo_SetValueInternal", type->type);
2022 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2023 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2024 if (!is_ok (&error)) {
2025 mono_error_set_pending_exception (&error);
2028 if (!vtable->initialized) {
2029 if (!mono_runtime_class_init_full (vtable, &error)) {
2030 mono_error_set_pending_exception (&error);
2034 mono_field_static_set_value (vtable, cf, v);
2036 mono_field_set_value (obj, cf, v);
2041 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2050 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2051 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2055 if (MONO_TYPE_IS_REFERENCE (f->type))
2056 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2058 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2061 ICALL_EXPORT MonoObject *
2062 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2064 MonoObject *o = NULL;
2065 MonoClassField *field = rfield->field;
2067 MonoDomain *domain = mono_object_domain (rfield);
2069 MonoTypeEnum def_type;
2070 const char *def_value;
2074 mono_class_init (field->parent);
2076 t = mono_field_get_type_checked (field, &error);
2077 if (!mono_error_ok (&error)) {
2078 mono_error_set_pending_exception (&error);
2082 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2083 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2087 if (image_is_dynamic (field->parent->image)) {
2088 MonoClass *klass = field->parent;
2089 int fidx = field - klass->fields;
2091 g_assert (fidx >= 0 && fidx < klass->field.count);
2092 g_assert (klass->ext);
2093 g_assert (klass->ext->field_def_values);
2094 def_type = klass->ext->field_def_values [fidx].def_type;
2095 def_value = klass->ext->field_def_values [fidx].data;
2096 if (def_type == MONO_TYPE_END) {
2097 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2101 def_value = mono_class_get_field_default_value (field, &def_type);
2102 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2104 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2109 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2113 case MONO_TYPE_BOOLEAN:
2116 case MONO_TYPE_CHAR:
2124 case MONO_TYPE_R8: {
2127 /* boxed value type */
2128 t = g_new0 (MonoType, 1);
2130 klass = mono_class_from_mono_type (t);
2132 o = mono_object_new_checked (domain, klass, &error);
2133 if (!mono_error_ok (&error)) {
2134 mono_error_set_pending_exception (&error);
2137 v = ((gchar *) o) + sizeof (MonoObject);
2138 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2139 if (mono_error_set_pending_exception (&error))
2143 case MONO_TYPE_STRING:
2144 case MONO_TYPE_CLASS:
2145 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2146 if (mono_error_set_pending_exception (&error))
2150 g_assert_not_reached ();
2156 ICALL_EXPORT MonoReflectionType*
2157 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2160 MonoReflectionType *ret;
2163 type = mono_field_get_type_checked (ref_field->field, &error);
2164 if (!mono_error_ok (&error)) {
2165 mono_error_set_pending_exception (&error);
2169 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2170 if (!mono_error_ok (&error)) {
2171 mono_error_set_pending_exception (&error);
2178 /* From MonoProperty.cs */
2180 PInfo_Attributes = 1,
2181 PInfo_GetMethod = 1 << 1,
2182 PInfo_SetMethod = 1 << 2,
2183 PInfo_ReflectedType = 1 << 3,
2184 PInfo_DeclaringType = 1 << 4,
2189 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2192 MonoReflectionType *rt;
2193 MonoReflectionMethod *rm;
2194 MonoDomain *domain = mono_object_domain (property);
2195 const MonoProperty *pproperty = property->property;
2197 if ((req_info & PInfo_ReflectedType) != 0) {
2198 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2199 if (mono_error_set_pending_exception (&error))
2202 MONO_STRUCT_SETREF (info, parent, rt);
2204 if ((req_info & PInfo_DeclaringType) != 0) {
2205 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2206 if (mono_error_set_pending_exception (&error))
2209 MONO_STRUCT_SETREF (info, declaring_type, rt);
2212 if ((req_info & PInfo_Name) != 0)
2213 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2215 if ((req_info & PInfo_Attributes) != 0)
2216 info->attrs = pproperty->attrs;
2218 if ((req_info & PInfo_GetMethod) != 0) {
2219 if (pproperty->get &&
2220 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2221 pproperty->get->klass == property->klass)) {
2222 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2223 if (mono_error_set_pending_exception (&error))
2229 MONO_STRUCT_SETREF (info, get, rm);
2231 if ((req_info & PInfo_SetMethod) != 0) {
2232 if (pproperty->set &&
2233 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2234 pproperty->set->klass == property->klass)) {
2235 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2236 if (mono_error_set_pending_exception (&error))
2242 MONO_STRUCT_SETREF (info, set, rm);
2245 * There may be other methods defined for properties, though, it seems they are not exposed
2246 * in the reflection API
2251 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2254 MonoReflectionType *rt;
2255 MonoReflectionMethod *rm;
2256 MonoDomain *domain = mono_object_domain (event);
2258 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2259 if (mono_error_set_pending_exception (&error))
2262 MONO_STRUCT_SETREF (info, reflected_type, rt);
2264 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2265 if (mono_error_set_pending_exception (&error))
2268 MONO_STRUCT_SETREF (info, declaring_type, rt);
2270 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2271 info->attrs = event->event->attrs;
2273 if (event->event->add) {
2274 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2275 if (mono_error_set_pending_exception (&error))
2281 MONO_STRUCT_SETREF (info, add_method, rm);
2283 if (event->event->remove) {
2284 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2285 if (mono_error_set_pending_exception (&error))
2291 MONO_STRUCT_SETREF (info, remove_method, rm);
2293 if (event->event->raise) {
2294 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2295 if (mono_error_set_pending_exception (&error))
2301 MONO_STRUCT_SETREF (info, raise_method, rm);
2303 #ifndef MONO_SMALL_CONFIG
2304 if (event->event->other) {
2306 while (event->event->other [n])
2308 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2309 if (mono_error_set_pending_exception (&error))
2311 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2313 for (i = 0; i < n; i++) {
2314 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2315 if (mono_error_set_pending_exception (&error))
2317 mono_array_setref (info->other_methods, i, rm);
2324 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2329 mono_class_setup_interfaces (klass, error);
2330 if (!mono_error_ok (error))
2333 for (i = 0; i < klass->interface_count; i++) {
2334 ic = klass->interfaces [i];
2335 g_hash_table_insert (ifaces, ic, ic);
2337 collect_interfaces (ic, ifaces, error);
2338 if (!mono_error_ok (error))
2344 MonoArray *iface_array;
2345 MonoGenericContext *context;
2349 } FillIfaceArrayData;
2352 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2354 MonoReflectionType *rt;
2355 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2356 MonoClass *ic = (MonoClass *)key;
2357 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2359 if (!mono_error_ok (data->error))
2362 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2363 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2364 if (!mono_error_ok (data->error))
2368 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2369 if (!mono_error_ok (data->error))
2372 mono_array_setref (data->iface_array, data->next_idx++, rt);
2375 mono_metadata_free_type (inflated);
2379 get_interfaces_hash (gconstpointer v1)
2381 MonoClass *k = (MonoClass*)v1;
2383 return k->type_token;
2386 ICALL_EXPORT MonoArray*
2387 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2390 MonoClass *klass = mono_class_from_mono_type (type->type);
2392 FillIfaceArrayData data = { 0 };
2395 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2397 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2398 data.context = mono_class_get_context (klass);
2399 klass = mono_class_get_generic_class (klass)->container_class;
2402 for (parent = klass; parent; parent = parent->parent) {
2403 mono_class_setup_interfaces (parent, &error);
2404 if (!mono_error_ok (&error))
2406 collect_interfaces (parent, iface_hash, &error);
2407 if (!mono_error_ok (&error))
2411 data.error = &error;
2412 data.domain = mono_object_domain (type);
2414 len = g_hash_table_size (iface_hash);
2416 g_hash_table_destroy (iface_hash);
2417 if (!data.domain->empty_types) {
2418 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2419 if (!is_ok (&error))
2422 return data.domain->empty_types;
2425 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2426 if (!is_ok (&error))
2428 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2429 if (!mono_error_ok (&error))
2432 g_hash_table_destroy (iface_hash);
2433 return data.iface_array;
2436 g_hash_table_destroy (iface_hash);
2437 mono_error_set_pending_exception (&error);
2442 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2444 gboolean variance_used;
2445 MonoClass *klass = mono_class_from_mono_type (type->type);
2446 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2447 MonoReflectionMethod *member;
2450 int i = 0, len, ioffset;
2454 mono_class_init_checked (klass, &error);
2455 if (mono_error_set_pending_exception (&error))
2457 mono_class_init_checked (iclass, &error);
2458 if (mono_error_set_pending_exception (&error))
2461 mono_class_setup_vtable (klass);
2463 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2467 len = mono_class_num_methods (iclass);
2468 domain = mono_object_domain (type);
2469 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2470 if (mono_error_set_pending_exception (&error))
2472 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2473 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2474 if (mono_error_set_pending_exception (&error))
2476 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2478 while ((method = mono_class_get_methods (iclass, &iter))) {
2479 member = mono_method_get_object_checked (domain, method, iclass, &error);
2480 if (mono_error_set_pending_exception (&error))
2482 mono_array_setref (*methods, i, member);
2483 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2484 if (mono_error_set_pending_exception (&error))
2486 mono_array_setref (*targets, i, member);
2493 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2496 MonoClass *klass = mono_class_from_mono_type (type->type);
2498 mono_class_init_checked (klass, &error);
2499 if (mono_error_set_pending_exception (&error))
2502 if (image_is_dynamic (klass->image)) {
2503 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2504 *packing = tb->packing_size;
2505 *size = tb->class_size;
2507 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2511 ICALL_EXPORT MonoReflectionType*
2512 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2515 MonoReflectionType *ret;
2518 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2519 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2520 mono_error_set_pending_exception (&error);
2524 klass = mono_class_from_mono_type (type->type);
2525 mono_class_init_checked (klass, &error);
2526 if (mono_error_set_pending_exception (&error))
2530 // GetElementType should only return a type for:
2531 // Array Pointer PassedByRef
2532 if (type->type->byref)
2533 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2534 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2535 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2536 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2537 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2541 mono_error_set_pending_exception (&error);
2546 ICALL_EXPORT MonoReflectionType*
2547 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2550 MonoReflectionType *ret;
2552 if (type->type->byref)
2555 MonoClass *klass = mono_class_from_mono_type (type->type);
2559 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2560 mono_error_set_pending_exception (&error);
2565 ICALL_EXPORT MonoBoolean
2566 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2568 return type->type->type == MONO_TYPE_PTR;
2571 ICALL_EXPORT MonoBoolean
2572 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2574 return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
2577 ICALL_EXPORT MonoBoolean
2578 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2580 return type->type->byref;
2583 ICALL_EXPORT MonoBoolean
2584 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2587 MonoClass *klass = mono_class_from_mono_type (type->type);
2588 mono_class_init_checked (klass, &error);
2589 if (mono_error_set_pending_exception (&error))
2592 return mono_class_is_com_object (klass);
2595 ICALL_EXPORT guint32
2596 ves_icall_reflection_get_token (MonoObject* obj)
2599 guint32 result = mono_reflection_get_token_checked (obj, &error);
2600 mono_error_set_pending_exception (&error);
2604 ICALL_EXPORT MonoReflectionModule*
2605 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2608 MonoReflectionModule *result = NULL;
2609 MonoClass *klass = mono_class_from_mono_type (type->type);
2610 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2611 mono_error_set_pending_exception (&error);
2615 ICALL_EXPORT MonoReflectionAssembly*
2616 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2619 MonoDomain *domain = mono_domain_get ();
2620 MonoClass *klass = mono_class_from_mono_type (type->type);
2621 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2622 mono_error_set_pending_exception (&error);
2626 ICALL_EXPORT MonoReflectionType*
2627 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2630 MonoReflectionType *ret;
2631 MonoDomain *domain = mono_domain_get ();
2634 if (type->type->byref)
2636 if (type->type->type == MONO_TYPE_VAR) {
2637 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2638 klass = param ? param->owner.klass : NULL;
2639 } else if (type->type->type == MONO_TYPE_MVAR) {
2640 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2641 klass = param ? param->owner.method->klass : NULL;
2643 klass = mono_class_from_mono_type (type->type)->nested_in;
2649 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2650 mono_error_set_pending_exception (&error);
2655 ICALL_EXPORT MonoStringHandle
2656 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2658 MonoDomain *domain = mono_domain_get ();
2659 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2660 MonoClass *klass = mono_class_from_mono_type (type);
2663 char *n = g_strdup_printf ("%s&", klass->name);
2664 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2670 return mono_string_new_handle (domain, klass->name, error);
2674 ICALL_EXPORT MonoStringHandle
2675 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2677 MonoDomain *domain = mono_domain_get ();
2678 MonoClass *klass = mono_class_from_mono_type_handle (type);
2680 while (klass->nested_in)
2681 klass = klass->nested_in;
2683 if (klass->name_space [0] == '\0')
2684 return NULL_HANDLE_STRING;
2686 return mono_string_new_handle (domain, klass->name_space, error);
2690 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2694 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2695 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2699 klass = mono_class_from_mono_type (type->type);
2705 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2707 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2710 ICALL_EXPORT MonoArray*
2711 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2714 MonoReflectionType *rt;
2716 MonoClass *klass, *pklass;
2717 MonoDomain *domain = mono_object_domain (type);
2720 klass = mono_class_from_mono_type (type->type);
2722 if (klass->generic_container) {
2723 MonoGenericContainer *container = klass->generic_container;
2724 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2725 if (mono_error_set_pending_exception (&error))
2727 for (i = 0; i < container->type_argc; ++i) {
2728 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2730 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2731 if (mono_error_set_pending_exception (&error))
2734 mono_array_setref (res, i, rt);
2736 } else if (mono_class_is_ginst (klass)) {
2737 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2738 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2739 if (mono_error_set_pending_exception (&error))
2741 for (i = 0; i < inst->type_argc; ++i) {
2742 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2743 if (mono_error_set_pending_exception (&error))
2746 mono_array_setref (res, i, rt);
2754 ICALL_EXPORT gboolean
2755 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2759 if (!IS_MONOTYPE (type))
2762 if (type->type->byref)
2765 klass = mono_class_from_mono_type (type->type);
2766 return klass->generic_container != NULL;
2769 ICALL_EXPORT MonoReflectionType*
2770 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2773 MonoReflectionType *ret;
2776 if (type->type->byref)
2779 klass = mono_class_from_mono_type (type->type);
2781 if (klass->generic_container) {
2782 return type; /* check this one */
2784 if (mono_class_is_ginst (klass)) {
2785 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2788 tb = mono_class_get_ref_info (generic_class);
2790 if (generic_class->wastypebuilder && tb)
2791 return (MonoReflectionType *)tb;
2793 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2794 mono_error_set_pending_exception (&error);
2802 ICALL_EXPORT MonoReflectionType*
2803 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2806 MonoReflectionType *ret;
2808 MonoType *geninst, **types;
2811 g_assert (IS_MONOTYPE (type));
2812 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2813 if (mono_error_set_pending_exception (&error))
2816 count = mono_array_length (type_array);
2817 types = g_new0 (MonoType *, count);
2819 for (i = 0; i < count; i++) {
2820 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2821 types [i] = t->type;
2824 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2827 mono_error_set_pending_exception (&error);
2831 klass = mono_class_from_mono_type (geninst);
2833 /*we might inflate to the GTD*/
2834 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2835 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2839 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2840 mono_error_set_pending_exception (&error);
2845 ICALL_EXPORT gboolean
2846 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2850 if (!IS_MONOTYPE (type))
2853 if (type->type->byref)
2856 klass = mono_class_from_mono_type (type->type);
2857 return mono_class_is_ginst (klass) || klass->generic_container != NULL;
2861 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2863 if (!IS_MONOTYPE (type))
2866 if (is_generic_parameter (type->type))
2867 return mono_type_get_generic_param_num (type->type);
2871 ICALL_EXPORT MonoGenericParamInfo *
2872 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2874 return mono_generic_param_info (type->type->data.generic_param);
2877 ICALL_EXPORT MonoBoolean
2878 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2880 return is_generic_parameter (type->type);
2883 ICALL_EXPORT MonoReflectionMethod*
2884 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2885 MonoReflectionMethod* generic)
2892 MonoReflectionMethod *ret = NULL;
2894 domain = ((MonoObject *)type)->vtable->domain;
2896 klass = mono_class_from_mono_type (type->type);
2897 mono_class_init_checked (klass, &error);
2898 if (mono_error_set_pending_exception (&error))
2902 while ((method = mono_class_get_methods (klass, &iter))) {
2903 if (method->token == generic->method->token) {
2904 ret = mono_method_get_object_checked (domain, method, klass, &error);
2905 if (mono_error_set_pending_exception (&error))
2913 ICALL_EXPORT MonoReflectionMethod *
2914 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2917 MonoType *type = ref_type->type;
2919 MonoReflectionMethod *ret = NULL;
2921 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2922 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2925 if (type->type == MONO_TYPE_VAR)
2928 method = mono_type_get_generic_param_owner (type)->owner.method;
2931 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2932 if (!mono_error_ok (&error))
2933 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2937 ICALL_EXPORT MonoBoolean
2938 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2940 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2944 ICALL_EXPORT MonoBoolean
2945 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2947 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2952 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2954 MonoDomain *domain = mono_domain_get ();
2955 MonoImage *image = method->method->klass->image;
2956 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2957 MonoTableInfo *tables = image->tables;
2958 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2959 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2960 guint32 im_cols [MONO_IMPLMAP_SIZE];
2961 guint32 scope_token;
2962 const char *import = NULL;
2963 const char *scope = NULL;
2965 if (image_is_dynamic (image)) {
2966 MonoReflectionMethodAux *method_aux =
2967 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2969 import = method_aux->dllentry;
2970 scope = method_aux->dll;
2973 if (!import || !scope) {
2974 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2979 if (piinfo->implmap_idx) {
2980 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2982 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2983 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2984 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2985 scope = mono_metadata_string_heap (image, scope_token);
2989 *flags = piinfo->piflags;
2990 *entry_point = mono_string_new (domain, import);
2991 *dll_name = mono_string_new (domain, scope);
2994 ICALL_EXPORT MonoReflectionMethod *
2995 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2997 MonoMethodInflated *imethod;
2999 MonoReflectionMethod *ret = NULL;
3002 if (method->method->is_generic)
3005 if (!method->method->is_inflated)
3008 imethod = (MonoMethodInflated *) method->method;
3010 result = imethod->declaring;
3011 /* Not a generic method. */
3012 if (!result->is_generic)
3015 if (image_is_dynamic (method->method->klass->image)) {
3016 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3017 MonoReflectionMethod *res;
3020 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3021 * the dynamic case as well ?
3023 mono_image_lock ((MonoImage*)image);
3024 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3025 mono_image_unlock ((MonoImage*)image);
3031 if (imethod->context.class_inst) {
3032 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3033 /*Generic methods gets the context of the GTD.*/
3034 if (mono_class_get_context (klass)) {
3035 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3036 if (!mono_error_ok (&error))
3041 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3043 if (!mono_error_ok (&error))
3044 mono_error_set_pending_exception (&error);
3048 ICALL_EXPORT gboolean
3049 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3051 return mono_method_signature (method->method)->generic_param_count != 0;
3054 ICALL_EXPORT gboolean
3055 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3057 return method->method->is_generic;
3060 ICALL_EXPORT MonoArray*
3061 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3064 MonoReflectionType *rt;
3069 domain = mono_object_domain (method);
3071 if (method->method->is_inflated) {
3072 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3075 count = inst->type_argc;
3076 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3077 if (mono_error_set_pending_exception (&error))
3080 for (i = 0; i < count; i++) {
3081 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3082 if (mono_error_set_pending_exception (&error))
3085 mono_array_setref (res, i, rt);
3092 count = mono_method_signature (method->method)->generic_param_count;
3093 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3094 if (mono_error_set_pending_exception (&error))
3097 for (i = 0; i < count; i++) {
3098 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3099 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3100 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3102 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3103 if (mono_error_set_pending_exception (&error))
3106 mono_array_setref (res, i, rt);
3112 ICALL_EXPORT MonoObject *
3113 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3117 * Invoke from reflection is supposed to always be a virtual call (the API
3118 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3119 * greater flexibility.
3121 MonoMethod *m = method->method;
3122 MonoMethodSignature *sig = mono_method_signature (m);
3125 void *obj = this_arg;
3129 if (mono_security_core_clr_enabled () &&
3130 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3131 mono_error_set_pending_exception (&error);
3135 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3136 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3137 mono_error_cleanup (&error); /* FIXME does this make sense? */
3138 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3143 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3144 if (!is_ok (&error)) {
3145 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3148 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3149 char *target_name = mono_type_get_full_name (m->klass);
3150 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3151 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3153 g_free (target_name);
3157 m = mono_object_get_virtual_method (this_arg, m);
3158 /* must pass the pointer to the value for valuetype methods */
3159 if (m->klass->valuetype)
3160 obj = mono_object_unbox (this_arg);
3161 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3162 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3167 if (sig->ret->byref) {
3168 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"));
3172 pcount = params? mono_array_length (params): 0;
3173 if (pcount != sig->param_count) {
3174 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3178 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this_arg) {
3179 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."));
3183 image = m->klass->image;
3184 if (image->assembly->ref_only) {
3185 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."));
3189 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3190 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3194 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3198 intptr_t *lower_bounds;
3199 pcount = mono_array_length (params);
3200 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3201 /* Note: the synthetized array .ctors have int32 as argument type */
3202 for (i = 0; i < pcount; ++i)
3203 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3205 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3206 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3207 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3208 if (!mono_error_ok (&error)) {
3209 mono_error_set_pending_exception (&error);
3213 for (i = 0; i < mono_array_length (arr); ++i) {
3214 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3215 if (!mono_error_ok (&error)) {
3216 mono_error_set_pending_exception (&error);
3219 mono_array_setref_fast (arr, i, subarray);
3221 return (MonoObject*)arr;
3224 if (m->klass->rank == pcount) {
3225 /* Only lengths provided. */
3226 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3227 if (!mono_error_ok (&error)) {
3228 mono_error_set_pending_exception (&error);
3232 return (MonoObject*)arr;
3234 g_assert (pcount == (m->klass->rank * 2));
3235 /* The arguments are lower-bound-length pairs */
3236 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3238 for (i = 0; i < pcount / 2; ++i) {
3239 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3240 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3243 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3244 if (!mono_error_ok (&error)) {
3245 mono_error_set_pending_exception (&error);
3249 return (MonoObject*)arr;
3252 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3253 mono_error_set_pending_exception (&error);
3257 #ifndef DISABLE_REMOTING
3258 ICALL_EXPORT MonoObject *
3259 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3262 MonoDomain *domain = mono_object_domain (method);
3263 MonoMethod *m = method->method;
3264 MonoMethodSignature *sig = mono_method_signature (m);
3265 MonoArray *out_args;
3267 int i, j, outarg_count = 0;
3269 if (m->klass == mono_defaults.object_class) {
3270 if (!strcmp (m->name, "FieldGetter")) {
3271 MonoClass *k = this_arg->vtable->klass;
3275 /* If this is a proxy, then it must be a CBO */
3276 if (k == mono_defaults.transparent_proxy_class) {
3277 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3278 this_arg = tp->rp->unwrapped_server;
3279 g_assert (this_arg);
3280 k = this_arg->vtable->klass;
3283 name = mono_array_get (params, MonoString *, 1);
3284 str = mono_string_to_utf8_checked (name, &error);
3285 if (mono_error_set_pending_exception (&error))
3289 MonoClassField* field = mono_class_get_field_from_name (k, str);
3292 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3293 if (field_klass->valuetype) {
3294 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3295 if (mono_error_set_pending_exception (&error))
3298 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3300 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3301 if (mono_error_set_pending_exception (&error))
3303 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3304 mono_array_setref (out_args, 0, result);
3311 g_assert_not_reached ();
3313 } else if (!strcmp (m->name, "FieldSetter")) {
3314 MonoClass *k = this_arg->vtable->klass;
3320 /* If this is a proxy, then it must be a CBO */
3321 if (k == mono_defaults.transparent_proxy_class) {
3322 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3323 this_arg = tp->rp->unwrapped_server;
3324 g_assert (this_arg);
3325 k = this_arg->vtable->klass;
3328 name = mono_array_get (params, MonoString *, 1);
3329 str = mono_string_to_utf8_checked (name, &error);
3330 if (mono_error_set_pending_exception (&error))
3334 MonoClassField* field = mono_class_get_field_from_name (k, str);
3337 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3338 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3340 if (field_klass->valuetype) {
3341 size = mono_type_size (field->type, &align);
3342 g_assert (size == mono_class_value_size (field_klass, NULL));
3343 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3345 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3348 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3349 if (mono_error_set_pending_exception (&error))
3351 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3360 g_assert_not_reached ();
3365 for (i = 0; i < mono_array_length (params); i++) {
3366 if (sig->params [i]->byref)
3370 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3371 if (mono_error_set_pending_exception (&error))
3374 /* handle constructors only for objects already allocated */
3375 if (!strcmp (method->method->name, ".ctor"))
3376 g_assert (this_arg);
3378 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3379 g_assert (!method->method->klass->valuetype);
3380 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3381 if (mono_error_set_pending_exception (&error))
3384 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3385 if (sig->params [i]->byref) {
3387 arg = mono_array_get (params, gpointer, i);
3388 mono_array_setref (out_args, j, arg);
3393 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3400 read_enum_value (const char *mem, int type)
3403 case MONO_TYPE_BOOLEAN:
3405 return *(guint8*)mem;
3407 return *(gint8*)mem;
3408 case MONO_TYPE_CHAR:
3410 return read16 (mem);
3412 return (gint16) read16 (mem);
3414 return read32 (mem);
3416 return (gint32) read32 (mem);
3419 return read64 (mem);
3421 g_assert_not_reached ();
3427 write_enum_value (char *mem, int type, guint64 value)
3431 case MONO_TYPE_I1: {
3432 guint8 *p = (guint8*)mem;
3438 case MONO_TYPE_CHAR: {
3439 guint16 *p = (guint16 *)mem;
3444 case MONO_TYPE_I4: {
3445 guint32 *p = (guint32 *)mem;
3450 case MONO_TYPE_I8: {
3451 guint64 *p = (guint64 *)mem;
3456 g_assert_not_reached ();
3461 ICALL_EXPORT MonoObject *
3462 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3470 domain = mono_object_domain (enumType);
3471 enumc = mono_class_from_mono_type (enumType->type);
3473 mono_class_init_checked (enumc, &error);
3474 if (mono_error_set_pending_exception (&error))
3477 etype = mono_class_enum_basetype (enumc);
3479 res = mono_object_new_checked (domain, enumc, &error);
3480 if (mono_error_set_pending_exception (&error))
3482 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3487 ICALL_EXPORT MonoBoolean
3488 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3490 int size = mono_class_value_size (a->vtable->klass, NULL);
3491 guint64 a_val = 0, b_val = 0;
3493 memcpy (&a_val, mono_object_unbox (a), size);
3494 memcpy (&b_val, mono_object_unbox (b), size);
3496 return (a_val & b_val) == b_val;
3499 ICALL_EXPORT MonoObject *
3500 ves_icall_System_Enum_get_value (MonoObject *eobj)
3512 g_assert (eobj->vtable->klass->enumtype);
3514 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3515 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3516 if (mono_error_set_pending_exception (&error))
3518 dst = (char *)res + sizeof (MonoObject);
3519 src = (char *)eobj + sizeof (MonoObject);
3520 size = mono_class_value_size (enumc, NULL);
3522 memcpy (dst, src, size);
3527 ICALL_EXPORT MonoReflectionType *
3528 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3531 MonoReflectionType *ret;
3535 klass = mono_class_from_mono_type (type->type);
3536 mono_class_init_checked (klass, &error);
3537 if (mono_error_set_pending_exception (&error))
3540 etype = mono_class_enum_basetype (klass);
3542 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3546 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3547 mono_error_set_pending_exception (&error);
3553 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3555 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3556 gpointer odata = (char *)other + sizeof (MonoObject);
3557 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3558 g_assert (basetype);
3563 if (eobj->vtable->klass != other->vtable->klass)
3566 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3567 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3568 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3571 return me > other ? 1 : -1; \
3574 switch (basetype->type) {
3576 COMPARE_ENUM_VALUES (guint8);
3578 COMPARE_ENUM_VALUES (gint8);
3579 case MONO_TYPE_CHAR:
3581 COMPARE_ENUM_VALUES (guint16);
3583 COMPARE_ENUM_VALUES (gint16);
3585 COMPARE_ENUM_VALUES (guint32);
3587 COMPARE_ENUM_VALUES (gint32);
3589 COMPARE_ENUM_VALUES (guint64);
3591 COMPARE_ENUM_VALUES (gint64);
3595 #undef COMPARE_ENUM_VALUES
3596 /* indicates that the enum was of an unsupported unerlying type */
3601 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3603 gpointer data = (char *)eobj + sizeof (MonoObject);
3604 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3605 g_assert (basetype);
3607 switch (basetype->type) {
3608 case MONO_TYPE_I1: {
3609 gint8 value = *((gint8*)data);
3610 return ((int)value ^ (int)value << 8);
3613 return *((guint8*)data);
3614 case MONO_TYPE_CHAR:
3616 return *((guint16*)data);
3618 case MONO_TYPE_I2: {
3619 gint16 value = *((gint16*)data);
3620 return ((int)(guint16)value | (((int)value) << 16));
3623 return *((guint32*)data);
3625 return *((gint32*)data);
3627 case MONO_TYPE_I8: {
3628 gint64 value = *((gint64*)data);
3629 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3632 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3637 ICALL_EXPORT MonoBoolean
3638 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionType *type, MonoArray **values, MonoArray **names)
3641 MonoDomain *domain = mono_object_domain (type);
3642 MonoClass *enumc = mono_class_from_mono_type (type->type);
3643 guint j = 0, nvalues;
3645 MonoClassField *field;
3647 guint64 field_value, previous_value = 0;
3648 gboolean sorted = TRUE;
3650 mono_class_init_checked (enumc, &error);
3651 if (mono_error_set_pending_exception (&error))
3655 if (!enumc->enumtype) {
3656 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3660 base_type = mono_class_enum_basetype (enumc)->type;
3662 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3663 *names = mono_array_new_checked (domain, mono_defaults.string_class, nvalues, &error);
3664 if (mono_error_set_pending_exception (&error))
3666 *values = mono_array_new_checked (domain, mono_defaults.uint64_class, nvalues, &error);
3667 if (mono_error_set_pending_exception (&error))
3671 while ((field = mono_class_get_fields (enumc, &iter))) {
3673 MonoTypeEnum def_type;
3675 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3677 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3679 if (mono_field_is_deleted (field))
3681 mono_array_setref (*names, j, mono_string_new (domain, mono_field_get_name (field)));
3683 p = mono_class_get_field_default_value (field, &def_type);
3684 /* len = */ mono_metadata_decode_blob_size (p, &p);
3686 field_value = read_enum_value (p, base_type);
3687 mono_array_set (*values, guint64, j, field_value);
3689 if (previous_value > field_value)
3692 previous_value = field_value;
3700 BFLAGS_IgnoreCase = 1,
3701 BFLAGS_DeclaredOnly = 2,
3702 BFLAGS_Instance = 4,
3704 BFLAGS_Public = 0x10,
3705 BFLAGS_NonPublic = 0x20,
3706 BFLAGS_FlattenHierarchy = 0x40,
3707 BFLAGS_InvokeMethod = 0x100,
3708 BFLAGS_CreateInstance = 0x200,
3709 BFLAGS_GetField = 0x400,
3710 BFLAGS_SetField = 0x800,
3711 BFLAGS_GetProperty = 0x1000,
3712 BFLAGS_SetProperty = 0x2000,
3713 BFLAGS_ExactBinding = 0x10000,
3714 BFLAGS_SuppressChangeType = 0x20000,
3715 BFLAGS_OptionalParamBinding = 0x40000
3718 ICALL_EXPORT GPtrArray*
3719 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3722 MonoClass *startklass, *klass;
3725 int (*compare_func) (const char *s1, const char *s2) = NULL;
3726 MonoClassField *field;
3728 if (type->type->byref) {
3729 return g_ptr_array_new ();
3732 mono_error_init (&error);
3734 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3736 klass = startklass = mono_class_from_mono_type (type->type);
3738 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3741 if (mono_class_has_failure (klass)) {
3742 mono_error_set_for_class_failure (&error, klass);
3747 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3748 guint32 flags = mono_field_get_flags (field);
3750 if (mono_field_is_deleted_with_flags (field, flags))
3752 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3753 if (bflags & BFLAGS_Public)
3755 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3756 if (bflags & BFLAGS_NonPublic) {
3763 if (flags & FIELD_ATTRIBUTE_STATIC) {
3764 if (bflags & BFLAGS_Static)
3765 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3768 if (bflags & BFLAGS_Instance)
3775 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3778 g_ptr_array_add (ptr_array, field);
3780 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3786 g_ptr_array_free (ptr_array, TRUE);
3787 mono_error_set_pending_exception (&error);
3792 method_nonpublic (MonoMethod* method, gboolean start_klass)
3794 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3795 case METHOD_ATTRIBUTE_ASSEM:
3796 return (start_klass || mono_defaults.generic_ilist_class);
3797 case METHOD_ATTRIBUTE_PRIVATE:
3799 case METHOD_ATTRIBUTE_PUBLIC:
3807 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3810 MonoClass *startklass;
3814 /*FIXME, use MonoBitSet*/
3815 guint32 method_slots_default [8];
3816 guint32 *method_slots = NULL;
3817 int (*compare_func) (const char *s1, const char *s2) = NULL;
3819 array = g_ptr_array_new ();
3821 mono_error_init (error);
3824 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3826 /* An optimization for calls made from Delegate:CreateDelegate () */
3827 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3828 method = mono_get_delegate_invoke (klass);
3831 g_ptr_array_add (array, method);
3835 mono_class_setup_methods (klass);
3836 mono_class_setup_vtable (klass);
3837 if (mono_class_has_failure (klass))
3840 if (is_generic_parameter (&klass->byval_arg))
3841 nslots = mono_class_get_vtable_size (klass->parent);
3843 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3844 if (nslots >= sizeof (method_slots_default) * 8) {
3845 method_slots = g_new0 (guint32, nslots / 32 + 1);
3847 method_slots = method_slots_default;
3848 memset (method_slots, 0, sizeof (method_slots_default));
3851 mono_class_setup_methods (klass);
3852 mono_class_setup_vtable (klass);
3853 if (mono_class_has_failure (klass))
3857 while ((method = mono_class_get_methods (klass, &iter))) {
3859 if (method->slot != -1) {
3860 g_assert (method->slot < nslots);
3861 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3863 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3864 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3867 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3869 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3870 if (bflags & BFLAGS_Public)
3872 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3878 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3879 if (bflags & BFLAGS_Static)
3880 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3883 if (bflags & BFLAGS_Instance)
3891 if (compare_func (name, method->name))
3896 g_ptr_array_add (array, method);
3898 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3900 if (method_slots != method_slots_default)
3901 g_free (method_slots);
3906 if (method_slots != method_slots_default)
3907 g_free (method_slots);
3908 g_ptr_array_free (array, TRUE);
3910 g_assert (mono_class_has_failure (klass));
3911 mono_error_set_for_class_failure (error, klass);
3915 ICALL_EXPORT GPtrArray*
3916 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3919 GPtrArray *method_array;
3922 klass = mono_class_from_mono_type (type->type);
3923 if (type->type->byref) {
3924 return g_ptr_array_new ();
3927 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3928 mono_error_set_pending_exception (&error);
3929 return method_array;
3932 ICALL_EXPORT GPtrArray*
3933 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3935 MonoClass *startklass, *klass;
3938 gpointer iter = NULL;
3939 GPtrArray *res_array;
3942 if (type->type->byref) {
3943 return g_ptr_array_new ();
3946 klass = startklass = mono_class_from_mono_type (type->type);
3948 mono_class_setup_methods (klass);
3949 if (mono_class_has_failure (klass)) {
3950 mono_error_init (&error);
3951 mono_error_set_for_class_failure (&error, klass);
3952 mono_error_set_pending_exception (&error);
3956 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3959 while ((method = mono_class_get_methods (klass, &iter))) {
3961 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3963 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3964 if (bflags & BFLAGS_Public)
3967 if (bflags & BFLAGS_NonPublic)
3973 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3974 if (bflags & BFLAGS_Static)
3975 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3978 if (bflags & BFLAGS_Instance)
3984 g_ptr_array_add (res_array, method);
3991 property_hash (gconstpointer data)
3993 MonoProperty *prop = (MonoProperty*)data;
3995 return g_str_hash (prop->name);
3999 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4001 if (method1->slot != -1 && method1->slot == method2->slot)
4004 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4005 if (method1->is_inflated)
4006 method1 = ((MonoMethodInflated*) method1)->declaring;
4007 if (method2->is_inflated)
4008 method2 = ((MonoMethodInflated*) method2)->declaring;
4011 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4015 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4017 // Properties are hide-by-name-and-signature
4018 if (!g_str_equal (prop1->name, prop2->name))
4021 /* If we see a property in a generic method, we want to
4022 compare the generic signatures, not the inflated signatures
4023 because we might conflate two properties that were
4027 public T this[T t] { getter { return t; } } // method 1
4028 public U this[U u] { getter { return u; } } // method 2
4031 If we see int Foo<int,int>::Item[int] we need to know if
4032 the indexer came from method 1 or from method 2, and we
4033 shouldn't conflate them. (Bugzilla 36283)
4035 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4038 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4045 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4050 return method_nonpublic (accessor, start_klass);
4053 ICALL_EXPORT GPtrArray*
4054 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4057 MonoClass *startklass, *klass;
4062 int (*compare_func) (const char *s1, const char *s2) = NULL;
4064 GHashTable *properties = NULL;
4065 GPtrArray *res_array;
4067 if (type->type->byref) {
4068 return g_ptr_array_new ();
4071 mono_error_init (&error);
4073 klass = startklass = mono_class_from_mono_type (type->type);
4075 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4077 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4079 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4081 mono_class_setup_methods (klass);
4082 mono_class_setup_vtable (klass);
4083 if (mono_class_has_failure (klass)) {
4084 mono_error_set_for_class_failure (&error, klass);
4089 while ((prop = mono_class_get_properties (klass, &iter))) {
4095 flags = method->flags;
4098 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4099 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4100 if (bflags & BFLAGS_Public)
4102 } else if (bflags & BFLAGS_NonPublic) {
4103 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4104 property_accessor_nonpublic(prop->set, startklass == klass)) {
4111 if (flags & METHOD_ATTRIBUTE_STATIC) {
4112 if (bflags & BFLAGS_Static)
4113 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4116 if (bflags & BFLAGS_Instance)
4124 if (propname != NULL && compare_func (propname, prop->name))
4127 if (g_hash_table_lookup (properties, prop))
4130 g_ptr_array_add (res_array, prop);
4132 g_hash_table_insert (properties, prop, prop);
4134 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4137 g_hash_table_destroy (properties);
4144 g_hash_table_destroy (properties);
4145 g_ptr_array_free (res_array, TRUE);
4147 mono_error_set_pending_exception (&error);
4153 event_hash (gconstpointer data)
4155 MonoEvent *event = (MonoEvent*)data;
4157 return g_str_hash (event->name);
4161 event_equal (MonoEvent *event1, MonoEvent *event2)
4163 // Events are hide-by-name
4164 return g_str_equal (event1->name, event2->name);
4167 ICALL_EXPORT GPtrArray*
4168 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4171 MonoClass *startklass, *klass;
4176 int (*compare_func) (const char *s1, const char *s2) = NULL;
4177 GHashTable *events = NULL;
4178 GPtrArray *res_array;
4180 if (type->type->byref) {
4181 return g_ptr_array_new ();
4184 mono_error_init (&error);
4186 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4188 res_array = g_ptr_array_sized_new (4);
4190 klass = startklass = mono_class_from_mono_type (type->type);
4192 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4194 mono_class_setup_methods (klass);
4195 mono_class_setup_vtable (klass);
4196 if (mono_class_has_failure (klass)) {
4197 mono_error_set_for_class_failure (&error, klass);
4202 while ((event = mono_class_get_events (klass, &iter))) {
4204 method = event->add;
4206 method = event->remove;
4208 method = event->raise;
4210 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4211 if (bflags & BFLAGS_Public)
4213 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4214 if (bflags & BFLAGS_NonPublic)
4219 if (bflags & BFLAGS_NonPublic)
4225 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4226 if (bflags & BFLAGS_Static)
4227 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4230 if (bflags & BFLAGS_Instance)
4235 if (bflags & BFLAGS_Instance)
4240 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4243 if (g_hash_table_lookup (events, event))
4246 g_ptr_array_add (res_array, event);
4248 g_hash_table_insert (events, event, event);
4250 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4253 g_hash_table_destroy (events);
4259 g_hash_table_destroy (events);
4261 g_ptr_array_free (res_array, TRUE);
4263 mono_error_set_pending_exception (&error);
4267 ICALL_EXPORT GPtrArray *
4268 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4274 GPtrArray *res_array;
4276 if (type->type->byref) {
4277 return g_ptr_array_new ();
4280 klass = mono_class_from_mono_type (type->type);
4283 * If a nested type is generic, return its generic type definition.
4284 * Note that this means that the return value is essentially the set
4285 * of nested types of the generic type definition of @klass.
4287 * A note in MSDN claims that a generic type definition can have
4288 * nested types that aren't generic. In any case, the container of that
4289 * nested type would be the generic type definition.
4291 if (mono_class_is_ginst (klass))
4292 klass = mono_class_get_generic_class (klass)->container_class;
4294 res_array = g_ptr_array_new ();
4297 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4299 if ((nested->flags & 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);
4318 ICALL_EXPORT MonoReflectionType*
4319 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4322 MonoReflectionType *ret;
4324 MonoType *type = NULL;
4325 MonoTypeNameParse info;
4326 gboolean type_resolve;
4328 /* On MS.NET, this does not fire a TypeResolve event */
4329 type_resolve = TRUE;
4330 str = mono_string_to_utf8_checked (name, &error);
4331 if (mono_error_set_pending_exception (&error))
4333 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4334 if (!mono_reflection_parse_type (str, &info)) {
4336 mono_reflection_free_type_info (&info);
4338 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4341 /*g_print ("failed parse\n");*/
4345 if (info.assembly.name) {
4347 mono_reflection_free_type_info (&info);
4349 /* 1.0 and 2.0 throw different exceptions */
4350 if (mono_defaults.generic_ilist_class)
4351 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4353 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4359 if (module != NULL) {
4360 if (module->image) {
4361 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4362 if (!is_ok (&error)) {
4364 mono_reflection_free_type_info (&info);
4365 mono_error_set_pending_exception (&error);
4372 if (assembly_is_dynamic (assembly->assembly)) {
4373 /* Enumerate all modules */
4374 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4378 if (abuilder->modules) {
4379 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4380 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4381 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4382 if (!is_ok (&error)) {
4384 mono_reflection_free_type_info (&info);
4385 mono_error_set_pending_exception (&error);
4393 if (!type && abuilder->loaded_modules) {
4394 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4395 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4396 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4397 if (!is_ok (&error)) {
4399 mono_reflection_free_type_info (&info);
4400 mono_error_set_pending_exception (&error);
4409 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4410 if (!is_ok (&error)) {
4412 mono_reflection_free_type_info (&info);
4413 mono_error_set_pending_exception (&error);
4418 mono_reflection_free_type_info (&info);
4420 MonoException *e = NULL;
4423 e = mono_get_exception_type_load (name, NULL);
4426 mono_set_pending_exception (e);
4430 if (type->type == MONO_TYPE_CLASS) {
4431 MonoClass *klass = mono_type_get_class (type);
4433 /* need to report exceptions ? */
4434 if (throwOnError && mono_class_has_failure (klass)) {
4435 /* report SecurityException (or others) that occured when loading the assembly */
4436 mono_error_set_for_class_failure (&error, klass);
4437 mono_error_set_pending_exception (&error);
4442 /* g_print ("got it\n"); */
4443 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4444 mono_error_set_pending_exception (&error);
4450 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4453 gchar *shadow_ini_file;
4456 /* Check for shadow-copied assembly */
4457 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4458 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4460 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4461 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4467 g_free (shadow_ini_file);
4468 if (content != NULL) {
4471 *filename = content;
4478 ICALL_EXPORT MonoString *
4479 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4481 MonoDomain *domain = mono_object_domain (assembly);
4482 MonoAssembly *mass = assembly->assembly;
4483 MonoString *res = NULL;
4488 if (g_path_is_absolute (mass->image->name)) {
4489 absolute = g_strdup (mass->image->name);
4490 dirname = g_path_get_dirname (absolute);
4492 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4493 dirname = g_strdup (mass->basedir);
4496 replace_shadow_path (domain, dirname, &absolute);
4499 mono_icall_make_platform_path (absolute);
4502 uri = g_filename_to_uri (absolute, NULL, NULL);
4504 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4505 uri = g_strconcat (prepend, absolute, NULL);
4509 res = mono_string_new (domain, uri);
4516 ICALL_EXPORT MonoBoolean
4517 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4519 MonoAssembly *mass = assembly->assembly;
4521 return mass->in_gac;
4524 ICALL_EXPORT MonoReflectionAssembly*
4525 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4530 MonoImageOpenStatus status;
4531 MonoReflectionAssembly* result = NULL;
4533 name = mono_string_to_utf8_checked (mname, &error);
4534 if (mono_error_set_pending_exception (&error))
4536 res = mono_assembly_load_with_partial_name (name, &status);
4542 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4544 mono_error_set_pending_exception (&error);
4548 ICALL_EXPORT MonoStringHandle
4549 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4551 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4552 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4553 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4556 ICALL_EXPORT MonoBoolean
4557 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4559 return assembly->assembly->ref_only;
4562 ICALL_EXPORT MonoStringHandle
4563 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4565 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4566 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4568 return mono_string_new_handle (domain, assembly->image->version, error);
4571 ICALL_EXPORT MonoReflectionMethod*
4572 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4575 MonoReflectionMethod *res = NULL;
4578 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4582 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4583 if (!mono_error_ok (&error))
4586 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4589 if (!mono_error_ok (&error))
4590 mono_error_set_pending_exception (&error);
4594 ICALL_EXPORT MonoReflectionModule*
4595 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4598 MonoReflectionModule *result = NULL;
4599 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4600 if (!mono_error_ok (&error))
4601 mono_error_set_pending_exception (&error);
4605 ICALL_EXPORT MonoArray*
4606 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4609 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4610 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4611 if (mono_error_set_pending_exception (&error))
4616 for (i = 0; i < table->rows; ++i) {
4617 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4618 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4623 ICALL_EXPORT MonoStringHandle
4624 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4627 guint8 aotid_sum = 0;
4628 MonoDomain* domain = mono_domain_get ();
4630 if (!domain->entry_assembly || !domain->entry_assembly->image)
4633 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4635 for (i = 0; i < 16; ++i)
4636 aotid_sum |= (*aotid)[i];
4641 gchar *guid = mono_guid_to_string((guint8*) aotid);
4642 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4648 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision, MonoError *error)
4650 static MonoMethod *create_version = NULL;
4654 mono_error_init (error);
4657 if (!create_version) {
4658 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4659 create_version = mono_method_desc_search_in_class (desc, mono_class_get_system_version_class ());
4660 g_assert (create_version);
4661 mono_method_desc_free (desc);
4667 args [3] = &revision;
4668 result = mono_object_new_checked (domain, mono_class_get_system_version_class (), error);
4669 return_val_if_nok (error, NULL);
4671 mono_runtime_invoke_checked (create_version, result, args, error);
4672 return_val_if_nok (error, NULL);
4677 ICALL_EXPORT MonoArray*
4678 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4682 MonoDomain *domain = mono_object_domain (assembly);
4684 static MonoMethod *create_culture = NULL;
4685 MonoImage *image = assembly->assembly->image;
4689 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4692 result = mono_array_new_checked (domain, mono_class_get_assembly_name_class (), count, &error);
4693 if (mono_error_set_pending_exception (&error))
4697 if (count > 0 && !create_culture) {
4698 MonoMethodDesc *desc = mono_method_desc_new (
4699 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4700 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4701 g_assert (create_culture);
4702 mono_method_desc_free (desc);
4705 for (i = 0; i < count; i++) {
4706 MonoObject *version;
4707 MonoReflectionAssemblyName *aname;
4708 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4710 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4712 aname = (MonoReflectionAssemblyName *) mono_object_new_checked (
4713 domain, mono_class_get_assembly_name_class (), &error);
4714 if (mono_error_set_pending_exception (&error))
4717 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4719 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4720 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4721 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4722 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4723 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4724 aname->versioncompat = 1; /* SameMachine (default) */
4725 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4727 version = create_version (domain, aname->major, aname->minor, aname->build, aname->revision, &error);
4728 if (mono_error_set_pending_exception (&error))
4731 MONO_OBJECT_SETREF (aname, version, version);
4733 if (create_culture) {
4735 MonoBoolean assembly_ref = 1;
4736 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4737 args [1] = &assembly_ref;
4739 o = mono_runtime_invoke_checked (create_culture, NULL, args, &error);
4740 if (mono_error_set_pending_exception (&error))
4743 MONO_OBJECT_SETREF (aname, cultureInfo, o);
4746 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4747 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4748 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4750 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4751 /* public key token isn't copied - the class library will
4752 automatically generate it from the public key if required */
4753 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4754 if (mono_error_set_pending_exception (&error))
4757 MONO_OBJECT_SETREF (aname, publicKey, pkey);
4758 memcpy (mono_array_addr (pkey, guint8, 0), pkey_ptr, pkey_len);
4760 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4761 if (mono_error_set_pending_exception (&error))
4764 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4765 memcpy (mono_array_addr (keyToken, guint8, 0), pkey_ptr, pkey_len);
4768 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, &error);
4769 if (mono_error_set_pending_exception (&error))
4772 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4775 /* note: this function doesn't return the codebase on purpose (i.e. it can
4776 be used under partial trust as path information isn't present). */
4778 mono_array_setref (result, i, aname);
4783 /* move this in some file in mono/util/ */
4785 g_concat_dir_and_file (const char *dir, const char *file)
4787 g_return_val_if_fail (dir != NULL, NULL);
4788 g_return_val_if_fail (file != NULL, NULL);
4791 * If the directory name doesn't have a / on the end, we need
4792 * to add one so we get a proper path to the file
4794 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4795 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4797 return g_strconcat (dir, file, NULL);
4801 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4804 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4806 guint32 cols [MONO_MANIFEST_SIZE];
4807 guint32 impl, file_idx;
4811 char *n = mono_string_to_utf8_checked (name, &error);
4812 if (mono_error_set_pending_exception (&error))
4815 for (i = 0; i < table->rows; ++i) {
4816 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4817 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4818 if (strcmp (val, n) == 0)
4822 if (i == table->rows)
4825 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4828 * this code should only be called after obtaining the
4829 * ResourceInfo and handling the other cases.
4831 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4832 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4834 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4835 if (mono_error_set_pending_exception (&error) || !module)
4839 module = assembly->assembly->image;
4842 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4843 if (mono_error_set_pending_exception (&error))
4845 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4847 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4850 ICALL_EXPORT gboolean
4851 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4854 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4856 guint32 cols [MONO_MANIFEST_SIZE];
4857 guint32 file_cols [MONO_FILE_SIZE];
4861 n = mono_string_to_utf8_checked (name, &error);
4862 if (mono_error_set_pending_exception (&error))
4864 for (i = 0; i < table->rows; ++i) {
4865 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4866 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4867 if (strcmp (val, n) == 0)
4871 if (i == table->rows)
4874 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4875 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4878 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4879 case MONO_IMPLEMENTATION_FILE:
4880 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4881 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4882 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4883 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4884 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4885 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4888 info->location = RESOURCE_LOCATION_EMBEDDED;
4891 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4892 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4893 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4894 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4895 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4896 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4898 mono_set_pending_exception (ex);
4901 MonoReflectionAssembly *assm_obj;
4902 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4904 mono_error_set_pending_exception (&error);
4907 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4909 /* Obtain info recursively */
4910 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4911 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4914 case MONO_IMPLEMENTATION_EXP_TYPE:
4915 g_assert_not_reached ();
4923 ICALL_EXPORT MonoObject*
4924 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4927 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4928 MonoArray *result = NULL;
4933 /* check hash if needed */
4935 n = mono_string_to_utf8_checked (name, &error);
4936 if (mono_error_set_pending_exception (&error))
4939 for (i = 0; i < table->rows; ++i) {
4940 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4941 if (strcmp (val, n) == 0) {
4944 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4945 fn = mono_string_new (mono_object_domain (assembly), n);
4947 return (MonoObject*)fn;
4955 for (i = 0; i < table->rows; ++i) {
4956 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4960 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4961 if (mono_error_set_pending_exception (&error))
4966 for (i = 0; i < table->rows; ++i) {
4967 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4968 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4969 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4970 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4975 return (MonoObject*)result;
4978 ICALL_EXPORT MonoArray*
4979 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4982 MonoDomain *domain = mono_domain_get();
4985 int i, j, file_count = 0;
4986 MonoImage **modules;
4987 guint32 module_count, real_module_count;
4988 MonoTableInfo *table;
4989 guint32 cols [MONO_FILE_SIZE];
4990 MonoImage *image = assembly->assembly->image;
4992 g_assert (image != NULL);
4993 g_assert (!assembly_is_dynamic (assembly->assembly));
4995 table = &image->tables [MONO_TABLE_FILE];
4996 file_count = table->rows;
4998 modules = image->modules;
4999 module_count = image->module_count;
5001 real_module_count = 0;
5002 for (i = 0; i < module_count; ++i)
5004 real_module_count ++;
5006 klass = mono_class_get_module_class ();
5007 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
5008 if (mono_error_set_pending_exception (&error))
5011 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
5012 if (mono_error_set_pending_exception (&error))
5015 mono_array_setref (res, 0, image_obj);
5017 for (i = 0; i < module_count; ++i)
5019 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
5020 if (mono_error_set_pending_exception (&error))
5022 mono_array_setref (res, j, rm);
5026 for (i = 0; i < file_count; ++i, ++j) {
5027 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
5028 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
5029 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
5030 if (mono_error_set_pending_exception (&error))
5032 mono_array_setref (res, j, rm);
5035 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
5036 if (mono_error_set_pending_exception (&error))
5039 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
5040 mono_set_pending_exception (mono_get_exception_file_not_found2 (NULL, fname));
5043 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
5044 if (mono_error_set_pending_exception (&error))
5046 mono_array_setref (res, j, rm);
5053 ICALL_EXPORT MonoReflectionMethod*
5054 ves_icall_GetCurrentMethod (void)
5056 MonoReflectionMethod *res = NULL;
5059 MonoMethod *m = mono_method_get_last_managed ();
5062 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5066 while (m->is_inflated)
5067 m = ((MonoMethodInflated*)m)->declaring;
5069 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5070 mono_error_set_pending_exception (&error);
5076 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5079 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5082 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5083 //method is inflated, we should inflate it on the other class
5084 MonoGenericContext ctx;
5085 ctx.method_inst = inflated->context.method_inst;
5086 ctx.class_inst = inflated->context.class_inst;
5087 if (mono_class_is_ginst (klass))
5088 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5089 else if (klass->generic_container)
5090 ctx.class_inst = klass->generic_container->context.class_inst;
5091 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5092 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5096 mono_class_setup_methods (method->klass);
5097 if (mono_class_has_failure (method->klass))
5099 for (i = 0; i < method->klass->method.count; ++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 < klass->method.count);
5109 return klass->methods [offset];
5112 ICALL_EXPORT MonoReflectionMethod*
5113 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5115 MonoReflectionMethod *res = NULL;
5118 if (type && generic_check) {
5119 klass = mono_class_from_mono_type (type);
5120 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5123 if (method->klass != klass) {
5124 method = mono_method_get_equivalent_method (method, klass);
5129 klass = mono_class_from_mono_type (type);
5131 klass = method->klass;
5132 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5133 mono_error_set_pending_exception (&error);
5137 ICALL_EXPORT MonoReflectionMethodBody*
5138 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5141 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5142 mono_error_set_pending_exception (&error);
5146 ICALL_EXPORT MonoReflectionAssembly*
5147 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5150 MonoReflectionAssembly *result;
5151 MonoMethod *dest = NULL;
5153 mono_stack_walk_no_il (get_executing, &dest);
5155 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5157 mono_error_set_pending_exception (&error);
5162 ICALL_EXPORT MonoReflectionAssembly*
5163 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5166 MonoReflectionAssembly *result;
5167 MonoDomain* domain = mono_domain_get ();
5169 if (!domain->entry_assembly)
5172 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5174 mono_error_set_pending_exception (&error);
5178 ICALL_EXPORT MonoReflectionAssembly*
5179 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5184 MonoReflectionAssembly *result;
5187 mono_stack_walk_no_il (get_executing, &dest);
5189 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5193 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5196 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5198 mono_error_set_pending_exception (&error);
5202 ICALL_EXPORT MonoStringHandle
5203 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5204 gboolean assembly_qualified, MonoError *error)
5206 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5207 MonoType *type = MONO_HANDLE_RAW (object)->type;
5208 MonoTypeNameFormat format;
5209 MonoStringHandle res;
5213 format = assembly_qualified ?
5214 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5215 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5217 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5219 name = mono_type_get_name_full (type, format);
5221 return NULL_HANDLE_STRING;
5223 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5225 return NULL_HANDLE_STRING;
5228 res = mono_string_new_handle (domain, name, error);
5235 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5238 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5240 mono_class_init_checked (klass, &error);
5241 mono_error_set_pending_exception (&error);
5242 return mono_security_core_clr_class_level (klass);
5246 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5248 MonoClassField *field = rfield->field;
5249 return mono_security_core_clr_field_level (field, TRUE);
5253 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5255 MonoMethod *method = rfield->method;
5256 return mono_security_core_clr_method_level (method, TRUE);
5260 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token, MonoError *error)
5262 static MonoMethod *create_culture = NULL;
5266 const char *pkey_ptr;
5268 MonoBoolean assembly_ref = 0;
5270 mono_error_init (error);
5272 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
5273 aname->major = name->major;
5274 aname->minor = name->minor;
5275 aname->build = name->build;
5276 aname->flags = name->flags;
5277 aname->revision = name->revision;
5278 aname->hashalg = name->hash_alg;
5279 aname->versioncompat = 1; /* SameMachine (default) */
5280 aname->processor_architecture = name->arch;
5282 if (by_default_version) {
5283 MonoObject *version;
5285 version = create_version (domain, name->major, name->minor, name->build, name->revision, error);
5286 return_if_nok (error);
5288 MONO_OBJECT_SETREF (aname, version, version);
5292 if (absolute != NULL && *absolute != '\0') {
5295 codebase = g_strdup (absolute);
5297 mono_icall_make_platform_path (codebase);
5299 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5301 result = g_strconcat (prepend, codebase, NULL);
5307 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
5311 if (!create_culture) {
5312 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
5313 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
5314 g_assert (create_culture);
5315 mono_method_desc_free (desc);
5318 if (name->culture) {
5319 args [0] = mono_string_new (domain, name->culture);
5320 args [1] = &assembly_ref;
5322 obj = mono_runtime_invoke_checked (create_culture, NULL, args, error);
5323 return_if_nok (error);
5325 MONO_OBJECT_SETREF (aname, cultureInfo, obj);
5328 if (name->public_key) {
5329 pkey_ptr = (char*)name->public_key;
5330 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
5332 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, error);
5333 return_if_nok (error);
5334 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5335 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
5336 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5337 } else if (default_publickey) {
5338 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5339 return_if_nok (error);
5340 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5341 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5344 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5345 if (name->public_key_token [0]) {
5349 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 8, error);
5350 return_if_nok (error);
5352 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5353 p = mono_array_addr (keyToken, char, 0);
5355 for (i = 0, j = 0; i < 8; i++) {
5356 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
5357 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
5360 } else if (default_token) {
5361 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5362 return_if_nok (error);
5363 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5367 ICALL_EXPORT MonoString *
5368 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5370 MonoDomain *domain = mono_object_domain (assembly);
5371 MonoAssembly *mass = assembly->assembly;
5375 name = mono_stringify_assembly_name (&mass->aname);
5376 res = mono_string_new (domain, name);
5382 ICALL_EXPORT MonoAssemblyName *
5383 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5385 return &mass->aname;
5389 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
5393 MonoImageOpenStatus status = MONO_IMAGE_OK;
5396 MonoAssemblyName name;
5399 filename = mono_string_to_utf8_checked (fname, &error);
5400 if (mono_error_set_pending_exception (&error))
5403 dirname = g_path_get_dirname (filename);
5404 replace_shadow_path (mono_domain_get (), dirname, &filename);
5407 image = mono_image_open (filename, &status);
5413 if (status == MONO_IMAGE_IMAGE_INVALID)
5414 exc = mono_get_exception_bad_image_format2 (NULL, fname);
5416 exc = mono_get_exception_file_not_found2 (NULL, fname);
5417 mono_set_pending_exception (exc);
5421 res = mono_assembly_fill_assembly_name (image, &name);
5423 mono_image_close (image);
5425 mono_set_pending_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5429 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE, FALSE, TRUE, &error);
5430 mono_error_set_pending_exception (&error);
5432 mono_image_close (image);
5436 ICALL_EXPORT MonoBoolean
5437 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5438 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5440 MonoBoolean result = FALSE;
5441 MonoDeclSecurityEntry entry;
5443 /* SecurityAction.RequestMinimum */
5444 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5445 *minimum = entry.blob;
5446 *minLength = entry.size;
5449 /* SecurityAction.RequestOptional */
5450 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5451 *optional = entry.blob;
5452 *optLength = entry.size;
5455 /* SecurityAction.RequestRefuse */
5456 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5457 *refused = entry.blob;
5458 *refLength = entry.size;
5466 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5468 guint32 attrs, visibility;
5470 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5471 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5472 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5475 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5481 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **exceptions, MonoBoolean exportedOnly, MonoError *error)
5483 MonoReflectionType *rt;
5486 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5489 mono_error_init (error);
5491 /* we start the count from 1 because we skip the special type <Module> */
5494 for (i = 1; i < tdef->rows; ++i) {
5495 if (mono_module_type_is_visible (tdef, image, i + 1))
5499 count = tdef->rows - 1;
5501 res = mono_array_new_checked (domain, mono_defaults.runtimetype_class, count, error);
5502 return_val_if_nok (error, NULL);
5503 *exceptions = mono_array_new_checked (domain, mono_defaults.exception_class, count, error);
5504 return_val_if_nok (error, NULL);
5506 for (i = 1; i < tdef->rows; ++i) {
5507 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i + 1)) {
5508 klass = mono_class_get_checked (image, (i + 1) | MONO_TOKEN_TYPE_DEF, error);
5511 rt = mono_type_get_object_checked (domain, &klass->byval_arg, error);
5512 return_val_if_nok (error, NULL);
5514 mono_array_setref (res, count, rt);
5516 MonoException *ex = mono_error_convert_to_exception (error);
5517 mono_array_setref (*exceptions, count, ex);
5526 ICALL_EXPORT MonoArray*
5527 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
5530 MonoArray *res = NULL;
5531 MonoArray *exceptions = NULL;
5532 MonoImage *image = NULL;
5533 MonoTableInfo *table = NULL;
5536 int i, len, ex_count;
5538 domain = mono_object_domain (assembly);
5540 g_assert (!assembly_is_dynamic (assembly->assembly));
5541 image = assembly->assembly->image;
5542 table = &image->tables [MONO_TABLE_FILE];
5543 res = mono_module_get_types (domain, image, &exceptions, exportedOnly, &error);
5544 if (mono_error_set_pending_exception (&error))
5547 /* Append data from all modules in the assembly */
5548 for (i = 0; i < table->rows; ++i) {
5549 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5550 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, &error);
5551 if (mono_error_set_pending_exception (&error))
5557 res2 = mono_module_get_types (domain, loaded_image, &ex2, exportedOnly, &error);
5558 if (mono_error_set_pending_exception (&error))
5562 /* Append the new types to the end of the array */
5563 if (mono_array_length (res2) > 0) {
5565 MonoArray *res3, *ex3;
5567 len1 = mono_array_length (res);
5568 len2 = mono_array_length (res2);
5570 res3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5571 if (mono_error_set_pending_exception (&error))
5573 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5574 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5577 ex3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5578 if (mono_error_set_pending_exception (&error))
5580 mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
5581 mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
5588 /* the ReflectionTypeLoadException must have all the types (Types property),
5589 * NULL replacing types which throws an exception. The LoaderException must
5590 * contain all exceptions for NULL items.
5593 len = mono_array_length (res);
5596 for (i = 0; i < len; i++) {
5597 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (res, gpointer, i);
5601 klass = mono_type_get_class (t->type);
5602 if ((klass != NULL) && mono_class_has_failure (klass)) {
5603 /* keep the class in the list */
5604 list = g_list_append (list, klass);
5605 /* and replace Type with NULL */
5606 mono_array_setref (res, i, NULL);
5613 if (list || ex_count) {
5615 MonoException *exc = NULL;
5616 MonoArray *exl = NULL;
5617 int j, length = g_list_length (list) + ex_count;
5619 exl = mono_array_new_checked (domain, mono_defaults.exception_class, length, &error);
5620 if (mono_error_set_pending_exception (&error)) {
5624 /* Types for which mono_class_get_checked () succeeded */
5625 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5626 MonoException *exc = mono_class_get_exception_for_failure ((MonoClass *)tmp->data);
5627 mono_array_setref (exl, i, exc);
5629 /* Types for which it don't */
5630 for (j = 0; j < mono_array_length (exceptions); ++j) {
5631 MonoException *exc = mono_array_get (exceptions, MonoException*, j);
5633 g_assert (i < length);
5634 mono_array_setref (exl, i, exc);
5641 exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
5642 if (!is_ok (&error)) {
5643 mono_error_set_pending_exception (&error);
5646 mono_set_pending_exception (exc);
5654 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname)
5656 mono_assembly_name_free (aname);
5659 ICALL_EXPORT gboolean
5660 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5662 *is_version_definited = *is_token_defined = FALSE;
5664 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5667 ICALL_EXPORT MonoReflectionType*
5668 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5671 MonoReflectionType *ret;
5672 MonoDomain *domain = mono_object_domain (module);
5675 g_assert (module->image);
5677 if (image_is_dynamic (module->image) && ((MonoDynamicImage*)(module->image))->initial_image)
5678 /* These images do not have a global type */
5681 klass = mono_class_get_checked (module->image, 1 | MONO_TOKEN_TYPE_DEF, &error);
5682 if (!mono_error_ok (&error)) {
5683 mono_error_set_pending_exception (&error);
5687 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
5688 if (!mono_error_ok (&error)) {
5689 mono_error_set_pending_exception (&error);
5697 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5699 /*if (module->image)
5700 mono_image_close (module->image);*/
5703 ICALL_EXPORT MonoStringHandle
5704 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5706 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5707 MonoImage *image = MONO_HANDLE_RAW (refmodule)->image;
5710 return mono_string_new_handle (domain, image->guid, error);
5714 static inline gpointer
5715 mono_icall_module_get_hinstance (MonoReflectionModule *module)
5717 return (gpointer) (-1);
5719 #endif /* HOST_WIN32 */
5721 ICALL_EXPORT gpointer
5722 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
5724 return mono_icall_module_get_hinstance (module);
5728 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5730 if (image_is_dynamic (image)) {
5731 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5732 *pe_kind = dyn->pe_kind;
5733 *machine = dyn->machine;
5736 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5737 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5742 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5744 return (image->md_version_major << 16) | (image->md_version_minor);
5747 ICALL_EXPORT MonoArray*
5748 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5751 MonoArray *exceptions;
5754 if (!module->image) {
5755 MonoArray *arr = mono_array_new_checked (mono_object_domain (module), mono_defaults.runtimetype_class, 0, &error);
5756 mono_error_set_pending_exception (&error);
5761 res = mono_module_get_types (mono_object_domain (module), module->image, &exceptions, FALSE, &error);
5762 if (mono_error_set_pending_exception (&error))
5765 for (i = 0; i < mono_array_length (exceptions); ++i) {
5766 MonoException *ex = mono_array_get (exceptions, MonoException *, i);
5768 mono_set_pending_exception (ex);
5777 mono_memberref_is_method (MonoImage *image, guint32 token)
5779 if (!image_is_dynamic (image)) {
5780 guint32 cols [MONO_MEMBERREF_SIZE];
5782 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5783 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5784 mono_metadata_decode_blob_size (sig, &sig);
5785 return (*sig != 0x6);
5788 MonoClass *handle_class;
5790 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5791 mono_error_cleanup (&error); /* just probing, ignore error */
5795 return mono_defaults.methodhandle_class == handle_class;
5800 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5803 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5804 mono_array_addr (type_args, MonoType*, 0));
5806 context->class_inst = NULL;
5808 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5809 mono_array_addr (method_args, MonoType*, 0));
5811 context->method_inst = NULL;
5814 ICALL_EXPORT MonoType*
5815 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5818 int table = mono_metadata_token_table (token);
5819 int index = mono_metadata_token_index (token);
5820 MonoGenericContext context;
5823 *resolve_error = ResolveTokenError_Other;
5825 /* Validate token */
5826 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5827 (table != MONO_TABLE_TYPESPEC)) {
5828 *resolve_error = ResolveTokenError_BadTable;
5832 if (image_is_dynamic (image)) {
5833 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5834 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5835 mono_error_cleanup (&error);
5836 return klass ? &klass->byval_arg : NULL;
5839 init_generic_context_from_args (&context, type_args, method_args);
5840 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5841 mono_error_cleanup (&error);
5842 return klass ? &klass->byval_arg : NULL;
5845 if ((index <= 0) || (index > image->tables [table].rows)) {
5846 *resolve_error = ResolveTokenError_OutOfRange;
5850 init_generic_context_from_args (&context, type_args, method_args);
5851 klass = mono_class_get_checked (image, token, &error);
5853 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5854 if (!mono_error_ok (&error)) {
5855 mono_error_set_pending_exception (&error);
5860 return &klass->byval_arg;
5865 ICALL_EXPORT MonoMethod*
5866 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5869 int table = mono_metadata_token_table (token);
5870 int index = mono_metadata_token_index (token);
5871 MonoGenericContext context;
5874 *resolve_error = ResolveTokenError_Other;
5876 /* Validate token */
5877 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5878 (table != MONO_TABLE_MEMBERREF)) {
5879 *resolve_error = ResolveTokenError_BadTable;
5883 if (image_is_dynamic (image)) {
5884 if (table == MONO_TABLE_METHOD) {
5885 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5886 mono_error_cleanup (&error);
5890 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5891 *resolve_error = ResolveTokenError_BadTable;
5895 init_generic_context_from_args (&context, type_args, method_args);
5896 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5897 mono_error_cleanup (&error);
5901 if ((index <= 0) || (index > image->tables [table].rows)) {
5902 *resolve_error = ResolveTokenError_OutOfRange;
5905 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5906 *resolve_error = ResolveTokenError_BadTable;
5910 init_generic_context_from_args (&context, type_args, method_args);
5911 method = mono_get_method_checked (image, token, NULL, &context, &error);
5912 mono_error_set_pending_exception (&error);
5917 ICALL_EXPORT MonoString*
5918 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5921 int index = mono_metadata_token_index (token);
5923 *resolve_error = ResolveTokenError_Other;
5925 /* Validate token */
5926 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5927 *resolve_error = ResolveTokenError_BadTable;
5931 if (image_is_dynamic (image)) {
5932 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5933 mono_error_cleanup (&error);
5937 if ((index <= 0) || (index >= image->heap_us.size)) {
5938 *resolve_error = ResolveTokenError_OutOfRange;
5942 /* FIXME: What to do if the index points into the middle of a string ? */
5944 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5945 mono_error_set_pending_exception (&error);
5949 ICALL_EXPORT MonoClassField*
5950 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5954 int table = mono_metadata_token_table (token);
5955 int index = mono_metadata_token_index (token);
5956 MonoGenericContext context;
5957 MonoClassField *field;
5959 *resolve_error = ResolveTokenError_Other;
5961 /* Validate token */
5962 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5963 *resolve_error = ResolveTokenError_BadTable;
5967 if (image_is_dynamic (image)) {
5968 if (table == MONO_TABLE_FIELD) {
5969 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5970 mono_error_cleanup (&error);
5974 if (mono_memberref_is_method (image, token)) {
5975 *resolve_error = ResolveTokenError_BadTable;
5979 init_generic_context_from_args (&context, type_args, method_args);
5980 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5981 mono_error_cleanup (&error);
5985 if ((index <= 0) || (index > image->tables [table].rows)) {
5986 *resolve_error = ResolveTokenError_OutOfRange;
5989 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5990 *resolve_error = ResolveTokenError_BadTable;
5994 init_generic_context_from_args (&context, type_args, method_args);
5995 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5996 mono_error_set_pending_exception (&error);
6002 ICALL_EXPORT MonoObject*
6003 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
6007 int table = mono_metadata_token_table (token);
6009 *error = ResolveTokenError_Other;
6012 case MONO_TABLE_TYPEDEF:
6013 case MONO_TABLE_TYPEREF:
6014 case MONO_TABLE_TYPESPEC: {
6015 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
6017 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
6018 mono_error_set_pending_exception (&merror);
6025 case MONO_TABLE_METHOD:
6026 case MONO_TABLE_METHODSPEC: {
6027 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6029 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6030 mono_error_set_pending_exception (&merror);
6036 case MONO_TABLE_FIELD: {
6037 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6039 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6040 mono_error_set_pending_exception (&merror);
6046 case MONO_TABLE_MEMBERREF:
6047 if (mono_memberref_is_method (image, token)) {
6048 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6050 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6051 mono_error_set_pending_exception (&merror);
6058 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6060 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6061 mono_error_set_pending_exception (&merror);
6070 *error = ResolveTokenError_BadTable;
6076 ICALL_EXPORT MonoArray*
6077 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6080 int table = mono_metadata_token_table (token);
6081 int idx = mono_metadata_token_index (token);
6082 MonoTableInfo *tables = image->tables;
6087 *resolve_error = ResolveTokenError_OutOfRange;
6089 /* FIXME: Support other tables ? */
6090 if (table != MONO_TABLE_STANDALONESIG)
6093 if (image_is_dynamic (image))
6096 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6099 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6101 ptr = mono_metadata_blob_heap (image, sig);
6102 len = mono_metadata_decode_blob_size (ptr, &ptr);
6104 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6105 if (mono_error_set_pending_exception (&error))
6107 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6111 ICALL_EXPORT MonoBoolean
6112 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6118 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6124 check_for_invalid_type (MonoClass *klass, MonoError *error)
6128 mono_error_init (error);
6130 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6133 name = mono_type_get_full_name (klass);
6134 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6136 ICALL_EXPORT MonoReflectionType *
6137 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6140 MonoReflectionType *ret;
6141 MonoClass *klass, *aklass;
6143 klass = mono_class_from_mono_type (type->type);
6144 check_for_invalid_type (klass, &error);
6145 if (mono_error_set_pending_exception (&error))
6148 if (rank == 0) //single dimentional array
6149 aklass = mono_array_class_get (klass, 1);
6151 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6153 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6154 mono_error_set_pending_exception (&error);
6159 ICALL_EXPORT MonoReflectionType *
6160 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6163 MonoReflectionType *ret;
6166 klass = mono_class_from_mono_type (type->type);
6167 mono_class_init_checked (klass, &error);
6168 if (mono_error_set_pending_exception (&error))
6171 check_for_invalid_type (klass, &error);
6172 if (mono_error_set_pending_exception (&error))
6175 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6176 mono_error_set_pending_exception (&error);
6181 ICALL_EXPORT MonoReflectionType *
6182 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6185 MonoReflectionType *ret;
6186 MonoClass *klass, *pklass;
6188 klass = mono_class_from_mono_type (type->type);
6189 mono_class_init_checked (klass, &error);
6190 if (mono_error_set_pending_exception (&error))
6192 check_for_invalid_type (klass, &error);
6193 if (mono_error_set_pending_exception (&error))
6196 pklass = mono_ptr_class_get (type->type);
6198 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6199 mono_error_set_pending_exception (&error);
6204 ICALL_EXPORT MonoObject *
6205 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6206 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6209 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6210 MonoObject *delegate;
6212 MonoMethod *method = info->method;
6213 MonoMethodSignature *sig = mono_method_signature(method);
6215 mono_class_init_checked (delegate_class, &error);
6216 if (mono_error_set_pending_exception (&error))
6219 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6220 /* FIXME improve this exception message */
6221 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6223 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6224 mono_error_set_pending_exception (&error);
6228 if (mono_security_core_clr_enabled ()) {
6229 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6230 if (throwOnBindFailure)
6231 mono_error_set_pending_exception (&error);
6233 mono_error_cleanup (&error);
6238 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6239 if (!method->is_inflated) {
6240 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"));
6245 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6246 if (mono_error_set_pending_exception (&error))
6249 if (method_is_dynamic (method)) {
6250 /* Creating a trampoline would leak memory */
6251 func = mono_compile_method_checked (method, &error);
6252 if (mono_error_set_pending_exception (&error))
6255 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6256 method = mono_object_get_virtual_method (target, method);
6257 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6258 if (mono_error_set_pending_exception (&error))
6260 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6263 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6264 if (mono_error_set_pending_exception (&error))
6269 ICALL_EXPORT MonoMulticastDelegate *
6270 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6273 MonoMulticastDelegate *ret;
6275 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6277 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6278 if (mono_error_set_pending_exception (&error))
6281 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6286 ICALL_EXPORT MonoReflectionMethod*
6287 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6289 MonoReflectionMethod *ret = NULL;
6291 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6292 mono_error_set_pending_exception (&error);
6298 static inline gint32
6299 mono_array_get_byte_length (MonoArray *array)
6305 klass = array->obj.vtable->klass;
6307 if (array->bounds == NULL)
6308 length = array->max_length;
6311 for (i = 0; i < klass->rank; ++ i)
6312 length *= array->bounds [i].length;
6315 switch (klass->element_class->byval_arg.type) {
6318 case MONO_TYPE_BOOLEAN:
6322 case MONO_TYPE_CHAR:
6330 return length * sizeof (gpointer);
6341 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6343 return mono_array_get_byte_length (array);
6347 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6349 return mono_array_get (array, gint8, idx);
6353 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6355 mono_array_set (array, gint8, idx, value);
6358 ICALL_EXPORT MonoBoolean
6359 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6361 guint8 *src_buf, *dest_buf;
6364 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6368 g_assert (count >= 0);
6370 /* This is called directly from the class libraries without going through the managed wrapper */
6371 MONO_CHECK_ARG_NULL (src, FALSE);
6372 MONO_CHECK_ARG_NULL (dest, FALSE);
6374 /* watch out for integer overflow */
6375 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6378 src_buf = (guint8 *)src->vector + src_offset;
6379 dest_buf = (guint8 *)dest->vector + dest_offset;
6382 memcpy (dest_buf, src_buf, count);
6384 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6389 #ifndef DISABLE_REMOTING
6390 ICALL_EXPORT MonoObject *
6391 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6394 MonoDomain *domain = mono_object_domain (this_obj);
6396 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6397 MonoTransparentProxy *tp;
6401 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6402 if (mono_error_set_pending_exception (&error))
6405 tp = (MonoTransparentProxy*) res;
6407 MONO_OBJECT_SETREF (tp, rp, rp);
6408 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6409 klass = mono_class_from_mono_type (type);
6411 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6412 mono_class_setup_vtable (klass);
6413 if (mono_class_has_failure (klass)) {
6414 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6418 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6419 if (mono_error_set_pending_exception (&error))
6421 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6422 if (mono_error_set_pending_exception (&error))
6425 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6426 if (mono_error_set_pending_exception (&error))
6431 ICALL_EXPORT MonoReflectionType *
6432 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6435 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6436 mono_error_set_pending_exception (&error);
6442 /* System.Environment */
6445 ves_icall_System_Environment_get_UserName (void)
6447 /* using glib is more portable */
6448 return mono_string_new (mono_domain_get (), g_get_user_name ());
6453 mono_icall_get_machine_name (void)
6455 #if !defined(DISABLE_SOCKETS)
6459 #if defined _SC_HOST_NAME_MAX
6460 n = sysconf (_SC_HOST_NAME_MAX);
6464 buf = g_malloc (n+1);
6466 if (gethostname (buf, n) == 0){
6468 result = mono_string_new (mono_domain_get (), buf);
6475 return mono_string_new (mono_domain_get (), "mono");
6478 #endif /* !HOST_WIN32 */
6480 ICALL_EXPORT MonoString *
6481 ves_icall_System_Environment_get_MachineName (void)
6483 return mono_icall_get_machine_name ();
6488 mono_icall_get_platform (void)
6490 #if defined(__MACH__)
6493 // Notice that the value is hidden from user code, and only exposed
6494 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6495 // define and making assumptions based on Unix/128/4 values before there
6496 // was a MacOS define. Lots of code would assume that not-Unix meant
6497 // Windows, but in this case, it would be OSX.
6505 #endif /* !HOST_WIN32 */
6508 ves_icall_System_Environment_get_Platform (void)
6510 return mono_icall_get_platform ();
6514 static inline MonoString *
6515 mono_icall_get_new_line (void)
6517 return mono_string_new (mono_domain_get (), "\n");
6519 #endif /* !HOST_WIN32 */
6521 ICALL_EXPORT MonoString *
6522 ves_icall_System_Environment_get_NewLine (void)
6524 return mono_icall_get_new_line ();
6528 static inline MonoBoolean
6529 mono_icall_is_64bit_os (void)
6531 #if SIZEOF_VOID_P == 8
6534 #if defined(HAVE_SYS_UTSNAME_H)
6535 struct utsname name;
6537 if (uname (&name) >= 0) {
6538 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6544 #endif /* !HOST_WIN32 */
6546 ICALL_EXPORT MonoBoolean
6547 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6549 return mono_icall_is_64bit_os ();
6552 ICALL_EXPORT MonoStringHandle
6553 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6557 if (utf8_name == NULL)
6558 return NULL_HANDLE_STRING;
6560 value = g_getenv (utf8_name);
6563 return NULL_HANDLE_STRING;
6565 return mono_string_new_handle (mono_domain_get (), value, error);
6569 * There is no standard way to get at environ.
6572 #ifndef __MINGW32_VERSION
6573 #if defined(__APPLE__)
6574 #if defined (TARGET_OSX)
6575 /* Apple defines this in crt_externs.h but doesn't provide that header for
6576 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6577 * in fact exist on all implementations (so far)
6579 gchar ***_NSGetEnviron(void);
6580 #define environ (*_NSGetEnviron())
6582 static char *mono_environ[1] = { NULL };
6583 #define environ mono_environ
6584 #endif /* defined (TARGET_OSX) */
6592 ICALL_EXPORT MonoArray *
6593 ves_icall_System_Environment_GetCoomandLineArgs (void)
6596 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6597 mono_error_set_pending_exception (&error);
6603 mono_icall_get_environment_variable_names (void)
6613 for (e = environ; *e != 0; ++ e)
6616 domain = mono_domain_get ();
6617 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6618 if (mono_error_set_pending_exception (&error))
6622 for (e = environ; *e != 0; ++ e) {
6623 parts = g_strsplit (*e, "=", 2);
6625 str = mono_string_new (domain, *parts);
6626 mono_array_setref (names, n, str);
6636 #endif /* !HOST_WIN32 */
6638 ICALL_EXPORT MonoArray *
6639 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6641 return mono_icall_get_environment_variable_names ();
6646 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6648 gchar *utf8_name, *utf8_value;
6651 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6652 if (mono_error_set_pending_exception (&error))
6655 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6656 g_unsetenv (utf8_name);
6661 utf8_value = mono_string_to_utf8_checked (value, &error);
6662 if (!mono_error_ok (&error)) {
6664 mono_error_set_pending_exception (&error);
6667 g_setenv (utf8_name, utf8_value, TRUE);
6670 g_free (utf8_value);
6672 #endif /* !HOST_WIN32 */
6675 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6677 mono_icall_set_environment_variable (name, value);
6681 ves_icall_System_Environment_Exit (int result)
6683 mono_environment_exitcode_set (result);
6685 /* FIXME: There are some cleanup hangs that should be worked out, but
6686 * if the program is going to exit, everything will be cleaned up when
6687 * NaCl exits anyway.
6689 #ifndef __native_client__
6690 if (!mono_runtime_try_shutdown ())
6691 mono_thread_exit ();
6693 /* Suspend all managed threads since the runtime is going away */
6694 mono_thread_suspend_all_other_threads ();
6696 mono_runtime_quit ();
6699 /* we may need to do some cleanup here... */
6703 ICALL_EXPORT MonoStringHandle
6704 ves_icall_System_Environment_GetGacPath (MonoError *error)
6706 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6710 static inline MonoString *
6711 mono_icall_get_windows_folder_path (int folder)
6713 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6714 return mono_string_new (mono_domain_get (), "");
6716 #endif /* !HOST_WIN32 */
6718 ICALL_EXPORT MonoString*
6719 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6721 return mono_icall_get_windows_folder_path (folder);
6724 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6726 mono_icall_get_logical_drives (void)
6729 gunichar2 buf [256], *ptr, *dname;
6731 guint initial_size = 127, size = 128;
6734 MonoString *drivestr;
6735 MonoDomain *domain = mono_domain_get ();
6741 while (size > initial_size) {
6742 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6743 if (size > initial_size) {
6746 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6747 initial_size = size;
6761 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6762 if (mono_error_set_pending_exception (&error))
6769 while (*u16) { u16++; len ++; }
6770 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6771 if (mono_error_set_pending_exception (&error))
6774 mono_array_setref (result, ndrives++, drivestr);
6784 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6786 ICALL_EXPORT MonoArray *
6787 ves_icall_System_Environment_GetLogicalDrives (void)
6789 return mono_icall_get_logical_drives ();
6792 ICALL_EXPORT MonoString *
6793 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6796 gunichar2 volume_name [MAX_PATH + 1];
6798 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6800 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6801 mono_error_set_pending_exception (&error);
6805 ICALL_EXPORT MonoStringHandle
6806 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6808 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6811 static const char *encodings [] = {
6813 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6814 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6815 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6817 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6818 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6819 "x_unicode_2_0_utf_7",
6821 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6822 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6824 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6827 "unicodefffe", "utf_16be",
6834 * Returns the internal codepage, if the value of "int_code_page" is
6835 * 1 at entry, and we can not compute a suitable code page number,
6836 * returns the code page as a string
6838 ICALL_EXPORT MonoString*
6839 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6844 char *codepage = NULL;
6846 int want_name = *int_code_page;
6849 *int_code_page = -1;
6851 g_get_charset (&cset);
6852 c = codepage = g_strdup (cset);
6853 for (c = codepage; *c; c++){
6854 if (isascii (*c) && isalpha (*c))
6859 /* g_print ("charset: %s\n", cset); */
6861 /* handle some common aliases */
6864 for (i = 0; p != 0; ){
6867 p = encodings [++i];
6870 if (strcmp (p, codepage) == 0){
6871 *int_code_page = code;
6874 p = encodings [++i];
6877 if (strstr (codepage, "utf_8") != NULL)
6878 *int_code_page |= 0x10000000;
6881 if (want_name && *int_code_page == -1)
6882 return mono_string_new (mono_domain_get (), cset);
6887 ICALL_EXPORT MonoBoolean
6888 ves_icall_System_Environment_get_HasShutdownStarted (void)
6890 if (mono_runtime_is_shutting_down ())
6893 if (mono_domain_is_unloading (mono_domain_get ()))
6901 mono_icall_broadcast_setting_change (void)
6905 #endif /* !HOST_WIN32 */
6908 ves_icall_System_Environment_BroadcastSettingChange (void)
6910 mono_icall_broadcast_setting_change ();
6915 ves_icall_System_Environment_get_TickCount (void)
6917 /* this will overflow after ~24 days */
6918 return (gint32) (mono_msec_boottime () & 0xffffffff);
6922 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6927 #ifndef DISABLE_REMOTING
6928 ICALL_EXPORT MonoBoolean
6929 ves_icall_IsTransparentProxy (MonoObject *proxy)
6934 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6940 ICALL_EXPORT MonoReflectionMethod *
6941 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6942 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6944 MonoReflectionMethod *ret = NULL;
6949 MonoMethod **vtable;
6950 MonoMethod *res = NULL;
6952 MONO_CHECK_ARG_NULL (rtype, NULL);
6953 MONO_CHECK_ARG_NULL (rmethod, NULL);
6955 method = rmethod->method;
6956 klass = mono_class_from_mono_type (rtype->type);
6957 mono_class_init_checked (klass, &error);
6958 if (mono_error_set_pending_exception (&error))
6961 if (MONO_CLASS_IS_INTERFACE (klass))
6964 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6967 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6968 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6974 mono_class_setup_vtable (klass);
6975 vtable = klass->vtable;
6977 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6978 gboolean variance_used = FALSE;
6979 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6980 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6982 res = vtable [offs + method->slot];
6984 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6987 if (method->slot != -1)
6988 res = vtable [method->slot];
6994 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6995 mono_error_set_pending_exception (&error);
7000 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7006 klass = mono_class_from_mono_type (type->type);
7007 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
7008 if (!is_ok (&error)) {
7009 mono_error_set_pending_exception (&error);
7013 mono_vtable_set_is_remote (vtable, enable);
7016 #else /* DISABLE_REMOTING */
7019 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7021 g_assert_not_reached ();
7026 ICALL_EXPORT MonoObject *
7027 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
7034 domain = mono_object_domain (type);
7035 klass = mono_class_from_mono_type (type->type);
7036 mono_class_init_checked (klass, &error);
7037 if (mono_error_set_pending_exception (&error))
7040 if (MONO_CLASS_IS_INTERFACE (klass) || (klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
7041 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
7045 if (klass->rank >= 1) {
7046 g_assert (klass->rank == 1);
7047 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
7048 mono_error_set_pending_exception (&error);
7051 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
7052 if (!is_ok (&error)) {
7053 mono_error_set_pending_exception (&error);
7056 /* Bypass remoting object creation check */
7057 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7058 mono_error_set_pending_exception (&error);
7064 ICALL_EXPORT MonoStringHandle
7065 ves_icall_System_IO_get_temp_path (MonoError *error)
7067 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7070 #ifndef PLATFORM_NO_DRIVEINFO
7071 ICALL_EXPORT MonoBoolean
7072 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7073 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7077 ULARGE_INTEGER wapi_free_bytes_avail;
7078 ULARGE_INTEGER wapi_total_number_of_bytes;
7079 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7081 *error = ERROR_SUCCESS;
7082 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7083 &wapi_total_number_of_free_bytes);
7086 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7087 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7088 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7090 *free_bytes_avail = 0;
7091 *total_number_of_bytes = 0;
7092 *total_number_of_free_bytes = 0;
7093 *error = GetLastError ();
7099 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7100 static inline guint32
7101 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7103 return GetDriveType (mono_string_chars (root_path_name));
7105 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7107 ICALL_EXPORT guint32
7108 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7110 return mono_icall_drive_info_get_drive_type (root_path_name);
7113 #endif /* PLATFORM_NO_DRIVEINFO */
7115 ICALL_EXPORT gpointer
7116 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7119 gpointer result = mono_compile_method_checked (method, &error);
7120 mono_error_set_pending_exception (&error);
7124 ICALL_EXPORT MonoString *
7125 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7130 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7132 mono_icall_make_platform_path (path);
7134 mcpath = mono_string_new (mono_domain_get (), path);
7140 /* this is an icall */
7142 get_bundled_app_config (void)
7145 const gchar *app_config;
7148 gchar *config_file_name, *config_file_path;
7149 gsize len, config_file_path_length, config_ext_length;
7152 domain = mono_domain_get ();
7153 file = domain->setup->configuration_file;
7154 if (!file || file->length == 0)
7157 // Retrieve config file and remove the extension
7158 config_file_name = mono_string_to_utf8_checked (file, &error);
7159 if (mono_error_set_pending_exception (&error))
7161 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7162 if (!config_file_path)
7163 config_file_path = config_file_name;
7165 config_file_path_length = strlen (config_file_path);
7166 config_ext_length = strlen (".config");
7167 if (config_file_path_length <= config_ext_length)
7170 len = config_file_path_length - config_ext_length;
7171 module = (gchar *)g_malloc0 (len + 1);
7172 memcpy (module, config_file_path, len);
7173 // Get the config file from the module name
7174 app_config = mono_config_string_for_assembly_file (module);
7177 if (config_file_name != config_file_path)
7178 g_free (config_file_name);
7179 g_free (config_file_path);
7184 return mono_string_new (mono_domain_get (), app_config);
7187 static MonoStringHandle
7188 get_bundled_machine_config (MonoError *error)
7190 const gchar *machine_config;
7192 machine_config = mono_get_machine_config ();
7194 if (!machine_config)
7195 return NULL_HANDLE_STRING;
7197 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7200 ICALL_EXPORT MonoStringHandle
7201 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7203 return get_bundled_machine_config (error);
7207 ICALL_EXPORT MonoStringHandle
7208 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7210 return get_bundled_machine_config (error);
7213 ICALL_EXPORT MonoStringHandle
7214 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7216 return get_bundled_machine_config (error);
7220 ICALL_EXPORT MonoString *
7221 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7226 path = g_path_get_dirname (mono_get_config_dir ());
7228 mono_icall_make_platform_path (path);
7230 ipath = mono_string_new (mono_domain_get (), path);
7236 ICALL_EXPORT gboolean
7237 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7239 MonoPEResourceDataEntry *entry;
7242 if (!assembly || !result || !size)
7247 image = assembly->assembly->image;
7248 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7252 *result = mono_image_rva_map (image, entry->rde_data_offset);
7257 *size = entry->rde_size;
7262 ICALL_EXPORT MonoBoolean
7263 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7265 return mono_is_debugger_attached ();
7268 ICALL_EXPORT MonoBoolean
7269 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7271 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7272 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7278 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7280 if (mono_get_runtime_callbacks ()->debug_log)
7281 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7286 mono_icall_write_windows_debug_string (MonoString *message)
7288 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7290 #endif /* !HOST_WIN32 */
7293 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7295 mono_icall_write_windows_debug_string (message);
7298 /* Only used for value types */
7299 ICALL_EXPORT MonoObject *
7300 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7307 domain = mono_object_domain (type);
7308 klass = mono_class_from_mono_type (type->type);
7309 mono_class_init_checked (klass, &error);
7310 if (mono_error_set_pending_exception (&error))
7313 if (mono_class_is_nullable (klass))
7314 /* No arguments -> null */
7317 result = mono_object_new_checked (domain, klass, &error);
7318 mono_error_set_pending_exception (&error);
7322 ICALL_EXPORT MonoReflectionMethod *
7323 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7325 MonoReflectionMethod *ret = NULL;
7328 MonoClass *klass, *parent;
7329 MonoGenericContext *generic_inst = NULL;
7330 MonoMethod *method = m->method;
7331 MonoMethod *result = NULL;
7334 if (method->klass == NULL)
7337 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7338 MONO_CLASS_IS_INTERFACE (method->klass) ||
7339 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7342 slot = mono_method_get_vtable_slot (method);
7346 klass = method->klass;
7347 if (mono_class_is_ginst (klass)) {
7348 generic_inst = mono_class_get_context (klass);
7349 klass = mono_class_get_generic_class (klass)->container_class;
7354 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7355 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7356 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7357 or klass is the generic container class and generic_inst is the instantiation.
7359 when we go to the parent, if the parent is an open constructed type, we need to
7360 replace the type parameters by the definitions from the generic_inst, and then take it
7361 apart again into the klass and the generic_inst.
7363 For cases like this:
7364 class C<T> : B<T, int> {
7365 public override void Foo () { ... }
7367 class B<U,V> : A<HashMap<U,V>> {
7368 public override void Foo () { ... }
7371 public virtual void Foo () { ... }
7374 if at each iteration the parent isn't open, we can skip inflating it. if at some
7375 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7378 MonoGenericContext *parent_inst = NULL;
7379 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7380 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7381 if (!mono_error_ok (&error)) {
7382 mono_error_set_pending_exception (&error);
7386 if (mono_class_is_ginst (parent)) {
7387 parent_inst = mono_class_get_context (parent);
7388 parent = mono_class_get_generic_class (parent)->container_class;
7391 mono_class_setup_vtable (parent);
7392 if (parent->vtable_size <= slot)
7395 generic_inst = parent_inst;
7398 klass = klass->parent;
7401 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7402 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7403 if (!mono_error_ok (&error)) {
7404 mono_error_set_pending_exception (&error);
7408 generic_inst = NULL;
7410 if (mono_class_is_ginst (klass)) {
7411 generic_inst = mono_class_get_context (klass);
7412 klass = mono_class_get_generic_class (klass)->container_class;
7418 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7419 if (!mono_error_ok (&error)) {
7420 mono_error_set_pending_exception (&error);
7425 if (klass == method->klass)
7428 /*This is possible if definition == FALSE.
7429 * Do it here to be really sure we don't read invalid memory.
7431 if (slot >= klass->vtable_size)
7434 mono_class_setup_vtable (klass);
7436 result = klass->vtable [slot];
7437 if (result == NULL) {
7438 /* It is an abstract method */
7439 gboolean found = FALSE;
7440 gpointer iter = NULL;
7441 while ((result = mono_class_get_methods (klass, &iter))) {
7442 if (result->slot == slot) {
7447 /* found might be FALSE if we looked in an abstract class
7448 * that doesn't override an abstract method of its
7450 * abstract class Base {
7451 * public abstract void Foo ();
7453 * abstract class Derived : Base { }
7454 * class Child : Derived {
7455 * public override void Foo () { }
7458 * if m was Child.Foo and we ask for the base method,
7459 * then we get here with klass == Derived and found == FALSE
7461 /* but it shouldn't be the case that if we're looking
7462 * for the definition and didn't find a result; the
7463 * loop above should've taken us as far as we could
7465 g_assert (!(definition && !found));
7470 g_assert (result != NULL);
7472 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7473 mono_error_set_pending_exception (&error);
7477 ICALL_EXPORT MonoString*
7478 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7480 MonoMethod *method = m->method;
7482 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7487 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7489 iter->sig = *(MonoMethodSignature**)argsp;
7491 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7492 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7495 /* FIXME: it's not documented what start is exactly... */
7499 iter->args = argsp + sizeof (gpointer);
7501 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7503 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7506 ICALL_EXPORT MonoTypedRef
7507 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7509 guint32 i, arg_size;
7513 i = iter->sig->sentinelpos + iter->next_arg;
7515 g_assert (i < iter->sig->param_count);
7517 res.type = iter->sig->params [i];
7518 res.klass = mono_class_from_mono_type (res.type);
7519 arg_size = mono_type_stack_size (res.type, &align);
7520 #if defined(__arm__) || defined(__mips__)
7521 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7523 res.value = iter->args;
7524 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7525 /* Values are stored as 8 byte register sized objects, but 'value'
7526 * is dereferenced as a pointer in other routines.
7528 res.value = (char*)res.value + 4;
7530 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7531 if (arg_size <= sizeof (gpointer)) {
7533 int padding = arg_size - mono_type_size (res.type, &dummy);
7534 res.value = (guint8*)res.value + padding;
7537 iter->args = (char*)iter->args + arg_size;
7540 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7545 ICALL_EXPORT MonoTypedRef
7546 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7548 guint32 i, arg_size;
7552 i = iter->sig->sentinelpos + iter->next_arg;
7554 g_assert (i < iter->sig->param_count);
7556 while (i < iter->sig->param_count) {
7557 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7559 res.type = iter->sig->params [i];
7560 res.klass = mono_class_from_mono_type (res.type);
7561 /* FIXME: endianess issue... */
7562 arg_size = mono_type_stack_size (res.type, &align);
7563 #if defined(__arm__) || defined(__mips__)
7564 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7566 res.value = iter->args;
7567 iter->args = (char*)iter->args + arg_size;
7569 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7572 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7580 ICALL_EXPORT MonoType*
7581 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7585 i = iter->sig->sentinelpos + iter->next_arg;
7587 g_assert (i < iter->sig->param_count);
7589 return iter->sig->params [i];
7592 ICALL_EXPORT MonoObject*
7593 mono_TypedReference_ToObject (MonoTypedRef* tref)
7596 MonoObject *result = NULL;
7597 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7598 MonoObject** objp = (MonoObject **)tref->value;
7602 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7603 mono_error_set_pending_exception (&error);
7607 ICALL_EXPORT MonoTypedRef
7608 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7611 MonoReflectionField *f;
7613 MonoType *ftype = NULL;
7617 memset (&res, 0, sizeof (res));
7620 g_assert (mono_array_length (fields) > 0);
7622 klass = target->vtable->klass;
7624 for (i = 0; i < mono_array_length (fields); ++i) {
7625 f = mono_array_get (fields, MonoReflectionField*, i);
7627 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7630 if (f->field->parent != klass) {
7631 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7635 p = (guint8*)target + f->field->offset;
7637 p += f->field->offset - sizeof (MonoObject);
7638 klass = mono_class_from_mono_type (f->field->type);
7639 ftype = f->field->type;
7643 res.klass = mono_class_from_mono_type (ftype);
7650 prelink_method (MonoMethod *method, MonoError *error)
7652 const char *exc_class, *exc_arg;
7654 mono_error_init (error);
7655 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7657 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7659 mono_error_set_exception_instance (error,
7660 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7663 /* create the wrapper, too? */
7667 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7671 prelink_method (method->method, &error);
7672 mono_error_set_pending_exception (&error);
7676 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7679 MonoClass *klass = mono_class_from_mono_type (type->type);
7681 gpointer iter = NULL;
7683 mono_class_init_checked (klass, &error);
7684 if (mono_error_set_pending_exception (&error))
7687 while ((m = mono_class_get_methods (klass, &iter))) {
7688 prelink_method (m, &error);
7689 if (mono_error_set_pending_exception (&error))
7694 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7696 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7697 gint32 const **exponents,
7698 gunichar2 const **digitLowerTable,
7699 gunichar2 const **digitUpperTable,
7700 gint64 const **tenPowersList,
7701 gint32 const **decHexDigits)
7703 *mantissas = Formatter_MantissaBitsTable;
7704 *exponents = Formatter_TensExponentTable;
7705 *digitLowerTable = Formatter_DigitLowerTable;
7706 *digitUpperTable = Formatter_DigitUpperTable;
7707 *tenPowersList = Formatter_TenPowersList;
7708 *decHexDigits = Formatter_DecHexDigits;
7712 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7713 * and avoid useless allocations.
7716 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7718 MonoReflectionType *rt;
7722 mono_error_init (error);
7723 for (i = 0; i < type->num_mods; ++i) {
7724 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7729 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7730 return_val_if_nok (error, NULL);
7732 for (i = 0; i < type->num_mods; ++i) {
7733 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7734 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7735 return_val_if_nok (error, NULL);
7737 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7738 return_val_if_nok (error, NULL);
7740 mono_array_setref (res, count, rt);
7747 ICALL_EXPORT MonoArray*
7748 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7751 MonoType *type = param->ClassImpl->type;
7752 MonoClass *member_class = mono_object_class (param->MemberImpl);
7753 MonoMethod *method = NULL;
7756 MonoMethodSignature *sig;
7759 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7760 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7761 method = rmethod->method;
7762 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7763 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7764 if (!(method = prop->property->get))
7765 method = prop->property->set;
7768 char *type_name = mono_type_get_full_name (member_class);
7769 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7770 MonoException *ex = mono_get_exception_not_supported (msg);
7773 mono_set_pending_exception (ex);
7777 image = method->klass->image;
7778 pos = param->PositionImpl;
7779 sig = mono_method_signature (method);
7783 type = sig->params [pos];
7785 res = type_array_from_modifiers (image, type, optional, &error);
7786 mono_error_set_pending_exception (&error);
7791 get_property_type (MonoProperty *prop)
7793 MonoMethodSignature *sig;
7795 sig = mono_method_signature (prop->get);
7797 } else if (prop->set) {
7798 sig = mono_method_signature (prop->set);
7799 return sig->params [sig->param_count - 1];
7804 ICALL_EXPORT MonoArray*
7805 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7808 MonoType *type = get_property_type (property->property);
7809 MonoImage *image = property->klass->image;
7814 res = type_array_from_modifiers (image, type, optional, &error);
7815 mono_error_set_pending_exception (&error);
7820 *Construct a MonoType suited to be used to decode a constant blob object.
7822 * @type is the target type which will be constructed
7823 * @blob_type is the blob type, for example, that comes from the constant table
7824 * @real_type is the expected constructed type.
7827 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7829 type->type = blob_type;
7830 type->data.klass = NULL;
7831 if (blob_type == MONO_TYPE_CLASS)
7832 type->data.klass = mono_defaults.object_class;
7833 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7834 /* For enums, we need to use the base type */
7835 type->type = MONO_TYPE_VALUETYPE;
7836 type->data.klass = mono_class_from_mono_type (real_type);
7838 type->data.klass = mono_class_from_mono_type (real_type);
7841 ICALL_EXPORT MonoObject*
7842 property_info_get_default_value (MonoReflectionProperty *property)
7846 MonoProperty *prop = property->property;
7847 MonoType *type = get_property_type (prop);
7848 MonoDomain *domain = mono_object_domain (property);
7849 MonoTypeEnum def_type;
7850 const char *def_value;
7853 mono_class_init (prop->parent);
7855 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7856 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7860 def_value = mono_class_get_property_default_value (prop, &def_type);
7862 mono_type_from_blob_type (&blob_type, def_type, type);
7863 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7865 mono_error_set_pending_exception (&error);
7869 ICALL_EXPORT MonoBoolean
7870 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7873 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7874 MonoCustomAttrInfo *cinfo;
7877 mono_class_init_checked (attr_class, &error);
7878 if (mono_error_set_pending_exception (&error))
7881 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7882 if (!is_ok (&error)) {
7883 mono_error_set_pending_exception (&error);
7888 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7890 mono_custom_attrs_free (cinfo);
7894 ICALL_EXPORT MonoArray*
7895 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7897 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7902 mono_class_init_checked (attr_class, &error);
7903 if (mono_error_set_pending_exception (&error))
7907 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7908 if (!mono_error_ok (&error)) {
7909 mono_error_set_pending_exception (&error);
7916 ICALL_EXPORT MonoArray*
7917 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7921 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7922 mono_error_set_pending_exception (&error);
7927 ICALL_EXPORT MonoString*
7928 ves_icall_Mono_Runtime_GetDisplayName (void)
7931 MonoString *display_name;
7933 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7934 display_name = mono_string_new (mono_domain_get (), info);
7936 return display_name;
7939 ICALL_EXPORT MonoString*
7940 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7943 MonoString *message;
7947 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7948 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7951 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7953 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7954 if (mono_error_set_pending_exception (&error))
7961 ICALL_EXPORT gpointer
7962 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
7964 return GetCurrentProcess ();
7967 ICALL_EXPORT MonoBoolean
7968 ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
7970 return GetExitCodeProcess (handle, (guint32*) exitcode);
7974 static inline MonoBoolean
7975 mono_icall_close_process (gpointer handle)
7977 return CloseProcess (handle);
7979 #endif /* !HOST_WIN32 */
7981 ICALL_EXPORT MonoBoolean
7982 ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
7984 return mono_icall_close_process (handle);
7987 ICALL_EXPORT MonoBoolean
7988 ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode)
7990 return TerminateProcess (handle, exitcode);
7994 static inline gint32
7995 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7997 return WAIT_TIMEOUT;
7999 #endif /* !HOST_WIN32 */
8002 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
8004 return mono_icall_wait_for_input_idle (handle, milliseconds);
8007 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
8008 static inline MonoBoolean
8009 mono_icall_get_process_working_set_size (gpointer handle, gsize *min, gsize *max)
8011 return GetProcessWorkingSetSize (handle, min, max);
8013 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
8015 ICALL_EXPORT MonoBoolean
8016 ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
8018 return mono_icall_get_process_working_set_size (handle, min, max);
8021 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
8022 static inline MonoBoolean
8023 mono_icall_set_process_working_set_size (gpointer handle, gsize min, gsize max)
8025 return SetProcessWorkingSetSize (handle, min, max);
8027 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
8029 ICALL_EXPORT MonoBoolean
8030 ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
8032 return mono_icall_set_process_working_set_size (handle, min, max);
8035 ICALL_EXPORT MonoBoolean
8036 ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creationtime, gint64 *exittime, gint64 *kerneltime, gint64 *usertime)
8038 return GetProcessTimes (handle, (LPFILETIME) creationtime, (LPFILETIME) exittime, (LPFILETIME) kerneltime, (LPFILETIME) usertime);
8042 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
8044 return mono_process_current_pid ();
8047 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
8048 static inline gint32
8049 mono_icall_get_priority_class (gpointer handle)
8051 return GetPriorityClass (handle);
8053 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
8056 ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
8058 return mono_icall_get_priority_class (handle);
8061 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
8062 static inline MonoBoolean
8063 mono_icall_set_priority_class (gpointer handle, gint32 priorityClass)
8065 return SetPriorityClass (handle, priorityClass);
8067 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
8069 ICALL_EXPORT MonoBoolean
8070 ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
8072 return mono_icall_set_priority_class (handle, priorityClass);
8075 ICALL_EXPORT MonoBoolean
8076 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
8088 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
8090 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
8094 ICALL_EXPORT MonoObject*
8095 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
8097 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
8102 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
8104 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
8108 ICALL_EXPORT MonoObject*
8109 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
8111 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
8115 ICALL_EXPORT MonoBoolean
8116 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
8118 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
8123 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
8125 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
8129 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
8131 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
8136 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
8138 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
8142 ICALL_EXPORT mono_unichar2*
8143 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
8145 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
8152 #ifndef DISABLE_ICALL_TABLES
8154 #define ICALL_TYPE(id,name,first)
8155 #define ICALL(id,name,func) Icall_ ## id,
8156 #define HANDLES(inner) inner
8159 #include "metadata/icall-def.h"
8165 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8166 #define ICALL(id,name,func)
8168 #define HANDLES(inner) inner
8170 #include "metadata/icall-def.h"
8176 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8177 #define ICALL(id,name,func)
8179 #define HANDLES(inner) inner
8181 guint16 first_icall;
8184 static const IcallTypeDesc
8185 icall_type_descs [] = {
8186 #include "metadata/icall-def.h"
8190 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8193 #define HANDLES(inner) inner
8195 #define ICALL_TYPE(id,name,first)
8198 #ifdef HAVE_ARRAY_ELEM_INIT
8199 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8200 #define MSGSTRFIELD1(line) str##line
8202 static const struct msgstrtn_t {
8203 #define ICALL(id,name,func)
8205 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8206 #include "metadata/icall-def.h"
8208 } icall_type_names_str = {
8209 #define ICALL_TYPE(id,name,first) (name),
8210 #include "metadata/icall-def.h"
8213 static const guint16 icall_type_names_idx [] = {
8214 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8215 #include "metadata/icall-def.h"
8218 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8220 static const struct msgstr_t {
8222 #define ICALL_TYPE(id,name,first)
8223 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8224 #include "metadata/icall-def.h"
8226 } icall_names_str = {
8227 #define ICALL(id,name,func) (name),
8228 #include "metadata/icall-def.h"
8231 static const guint16 icall_names_idx [] = {
8232 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8233 #include "metadata/icall-def.h"
8236 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8242 #define ICALL_TYPE(id,name,first) name,
8243 #define ICALL(id,name,func)
8244 static const char* const
8245 icall_type_names [] = {
8246 #include "metadata/icall-def.h"
8250 #define icall_type_name_get(id) (icall_type_names [(id)])
8254 #define ICALL_TYPE(id,name,first)
8255 #define ICALL(id,name,func) name,
8256 static const char* const
8258 #include "metadata/icall-def.h"
8261 #define icall_name_get(id) icall_names [(id)]
8263 #endif /* !HAVE_ARRAY_ELEM_INIT */
8266 #define HANDLES(inner) inner
8269 #define ICALL_TYPE(id,name,first)
8270 #define ICALL(id,name,func) func,
8271 static const gconstpointer
8272 icall_functions [] = {
8273 #include "metadata/icall-def.h"
8277 #ifdef ENABLE_ICALL_SYMBOL_MAP
8279 #define HANDLES(inner) inner
8282 #define ICALL_TYPE(id,name,first)
8283 #define ICALL(id,name,func) #func,
8284 static const gconstpointer
8285 icall_symbols [] = {
8286 #include "metadata/icall-def.h"
8293 #define ICALL_TYPE(id,name,first)
8294 #define ICALL(id,name,func) 0,
8296 #define HANDLES(inner) 1,
8298 icall_uses_handles [] = {
8299 #include "metadata/icall-def.h"
8304 #endif /* DISABLE_ICALL_TABLES */
8306 static mono_mutex_t icall_mutex;
8307 static GHashTable *icall_hash = NULL;
8308 static GHashTable *jit_icall_hash_name = NULL;
8309 static GHashTable *jit_icall_hash_addr = NULL;
8312 mono_icall_init (void)
8314 #ifndef DISABLE_ICALL_TABLES
8317 /* check that tables are sorted: disable in release */
8320 const char *prev_class = NULL;
8321 const char *prev_method;
8323 for (i = 0; i < Icall_type_num; ++i) {
8324 const IcallTypeDesc *desc;
8327 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8328 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8329 prev_class = icall_type_name_get (i);
8330 desc = &icall_type_descs [i];
8331 num_icalls = icall_desc_num_icalls (desc);
8332 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8333 for (j = 0; j < num_icalls; ++j) {
8334 const char *methodn = icall_name_get (desc->first_icall + j);
8335 if (prev_method && strcmp (prev_method, methodn) >= 0)
8336 g_print ("method %s should come before method %s\n", methodn, prev_method);
8337 prev_method = methodn;
8343 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8344 mono_os_mutex_init (&icall_mutex);
8348 mono_icall_lock (void)
8350 mono_locks_os_acquire (&icall_mutex, IcallLock);
8354 mono_icall_unlock (void)
8356 mono_locks_os_release (&icall_mutex, IcallLock);
8360 mono_icall_cleanup (void)
8362 g_hash_table_destroy (icall_hash);
8363 g_hash_table_destroy (jit_icall_hash_name);
8364 g_hash_table_destroy (jit_icall_hash_addr);
8365 mono_os_mutex_destroy (&icall_mutex);
8369 * mono_add_internal_call:
8370 * @name: method specification to surface to the managed world
8371 * @method: pointer to a C method to invoke when the method is called
8373 * This method surfaces the C function pointed by @method as a method
8374 * that has been surfaced in managed code with the method specified in
8375 * @name as an internal call.
8377 * Internal calls are surfaced to all app domains loaded and they are
8378 * accessibly by a type with the specified name.
8380 * You must provide a fully qualified type name, that is namespaces
8381 * and type name, followed by a colon and the method name, with an
8382 * optional signature to bind.
8384 * For example, the following are all valid declarations:
8386 * "MyApp.Services.ScriptService:Accelerate"
8387 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8389 * You use method parameters in cases where there might be more than
8390 * one surface method to managed code. That way you can register different
8391 * internal calls for different method overloads.
8393 * The internal calls are invoked with no marshalling. This means that .NET
8394 * types like System.String are exposed as `MonoString *` parameters. This is
8395 * different than the way that strings are surfaced in P/Invoke.
8397 * For more information on how the parameters are marshalled, see the
8398 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8401 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8402 * reference for more information on the format of method descriptions.
8405 mono_add_internal_call (const char *name, gconstpointer method)
8409 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8411 mono_icall_unlock ();
8414 #ifndef DISABLE_ICALL_TABLES
8416 #ifdef HAVE_ARRAY_ELEM_INIT
8418 compare_method_imap (const void *key, const void *elem)
8420 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8421 return strcmp (key, method_name);
8425 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8427 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);
8430 return (nameslot - &icall_names_idx [0]);
8434 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8436 gsize slotnum = find_slot_icall (imap, name);
8439 return (gboolean)icall_uses_handles [slotnum];
8443 find_method_icall (const IcallTypeDesc *imap, const char *name)
8445 gsize slotnum = find_slot_icall (imap, name);
8448 return (gpointer)icall_functions [slotnum];
8452 compare_class_imap (const void *key, const void *elem)
8454 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8455 return strcmp (key, class_name);
8458 static const IcallTypeDesc*
8459 find_class_icalls (const char *name)
8461 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);
8464 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8467 #else /* HAVE_ARRAY_ELEM_INIT */
8470 compare_method_imap (const void *key, const void *elem)
8472 const char** method_name = (const char**)elem;
8473 return strcmp (key, *method_name);
8477 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8479 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8482 return nameslot - icall_names;
8486 find_method_icall (const IcallTypeDesc *imap, const char *name)
8488 gsize slotnum = find_slot_icall (imap, name);
8491 return (gpointer)icall_functions [slotnum];
8495 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8497 gsize slotnum = find_slot_icall (imap, name);
8500 return (gboolean)icall_uses_handles [slotnum];
8504 compare_class_imap (const void *key, const void *elem)
8506 const char** class_name = (const char**)elem;
8507 return strcmp (key, *class_name);
8510 static const IcallTypeDesc*
8511 find_class_icalls (const char *name)
8513 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8516 return &icall_type_descs [nameslot - icall_type_names];
8519 #endif /* HAVE_ARRAY_ELEM_INIT */
8521 #endif /* DISABLE_ICALL_TABLES */
8524 * we should probably export this as an helper (handle nested types).
8525 * Returns the number of chars written in buf.
8528 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8530 int nspacelen, cnamelen;
8531 nspacelen = strlen (klass->name_space);
8532 cnamelen = strlen (klass->name);
8533 if (nspacelen + cnamelen + 2 > bufsize)
8536 memcpy (buf, klass->name_space, nspacelen);
8537 buf [nspacelen ++] = '.';
8539 memcpy (buf + nspacelen, klass->name, cnamelen);
8540 buf [nspacelen + cnamelen] = 0;
8541 return nspacelen + cnamelen;
8544 #ifdef DISABLE_ICALL_TABLES
8546 no_icall_table (void)
8548 g_assert_not_reached ();
8553 * mono_lookup_internal_call_full:
8554 * @method: the method to look up
8555 * @uses_handles: out argument if method needs handles around managed objects.
8557 * Returns a pointer to the icall code for the given method. If
8558 * uses_handles is not NULL, it will be set to TRUE if the method
8559 * needs managed objects wrapped using the infrastructure in handle.h
8561 * If the method is not found, warns and returns NULL.
8564 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8569 int typelen = 0, mlen, siglen;
8571 #ifndef DISABLE_ICALL_TABLES
8572 const IcallTypeDesc *imap = NULL;
8575 g_assert (method != NULL);
8577 if (method->is_inflated)
8578 method = ((MonoMethodInflated *) method)->declaring;
8580 if (method->klass->nested_in) {
8581 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8585 mname [pos++] = '/';
8588 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8594 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8599 #ifndef DISABLE_ICALL_TABLES
8600 imap = find_class_icalls (mname);
8603 mname [typelen] = ':';
8604 mname [typelen + 1] = ':';
8606 mlen = strlen (method->name);
8607 memcpy (mname + typelen + 2, method->name, mlen);
8608 sigstart = mname + typelen + 2 + mlen;
8611 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8612 siglen = strlen (tmpsig);
8613 if (typelen + mlen + siglen + 6 > sizeof (mname))
8616 memcpy (sigstart + 1, tmpsig, siglen);
8617 sigstart [siglen + 1] = ')';
8618 sigstart [siglen + 2] = 0;
8623 res = g_hash_table_lookup (icall_hash, mname);
8626 *uses_handles = FALSE;
8627 mono_icall_unlock ();;
8630 /* try without signature */
8632 res = g_hash_table_lookup (icall_hash, mname);
8635 *uses_handles = FALSE;
8636 mono_icall_unlock ();
8640 #ifdef DISABLE_ICALL_TABLES
8641 mono_icall_unlock ();
8642 /* Fail only when the result is actually used */
8643 /* mono_marshal_get_native_wrapper () depends on this */
8644 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8645 return ves_icall_System_String_ctor_RedirectToCreateString;
8647 return no_icall_table;
8649 /* it wasn't found in the static call tables */
8652 *uses_handles = FALSE;
8653 mono_icall_unlock ();
8656 res = find_method_icall (imap, sigstart - mlen);
8659 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8660 mono_icall_unlock ();
8663 /* try _with_ signature */
8665 res = find_method_icall (imap, sigstart - mlen);
8668 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8669 mono_icall_unlock ();
8673 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8674 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8675 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8676 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8677 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");
8678 g_print ("If you see other errors or faults after this message they are probably related\n");
8679 g_print ("and you need to fix your mono install first.\n");
8681 mono_icall_unlock ();
8688 mono_lookup_internal_call (MonoMethod *method)
8690 return mono_lookup_internal_call_full (method, NULL);
8693 #ifdef ENABLE_ICALL_SYMBOL_MAP
8695 func_cmp (gconstpointer key, gconstpointer p)
8697 return (gsize)key - (gsize)*(gsize*)p;
8702 * mono_lookup_icall_symbol:
8704 * Given the icall METHOD, returns its C symbol.
8707 mono_lookup_icall_symbol (MonoMethod *m)
8709 #ifdef DISABLE_ICALL_TABLES
8710 g_assert_not_reached ();
8713 #ifdef ENABLE_ICALL_SYMBOL_MAP
8717 static gconstpointer *functions_sorted;
8718 static const char**symbols_sorted;
8719 static gboolean inited;
8724 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8725 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8726 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8727 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8728 /* Bubble sort the two arrays */
8732 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8733 if (functions_sorted [i] > functions_sorted [i + 1]) {
8736 tmp = functions_sorted [i];
8737 functions_sorted [i] = functions_sorted [i + 1];
8738 functions_sorted [i + 1] = tmp;
8739 tmp = symbols_sorted [i];
8740 symbols_sorted [i] = symbols_sorted [i + 1];
8741 symbols_sorted [i + 1] = tmp;
8748 func = mono_lookup_internal_call (m);
8751 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8755 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8757 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8758 g_assert_not_reached ();
8765 type_from_typename (char *type_name)
8767 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8769 if (!strcmp (type_name, "int"))
8770 klass = mono_defaults.int_class;
8771 else if (!strcmp (type_name, "ptr"))
8772 klass = mono_defaults.int_class;
8773 else if (!strcmp (type_name, "void"))
8774 klass = mono_defaults.void_class;
8775 else if (!strcmp (type_name, "int32"))
8776 klass = mono_defaults.int32_class;
8777 else if (!strcmp (type_name, "uint32"))
8778 klass = mono_defaults.uint32_class;
8779 else if (!strcmp (type_name, "int8"))
8780 klass = mono_defaults.sbyte_class;
8781 else if (!strcmp (type_name, "uint8"))
8782 klass = mono_defaults.byte_class;
8783 else if (!strcmp (type_name, "int16"))
8784 klass = mono_defaults.int16_class;
8785 else if (!strcmp (type_name, "uint16"))
8786 klass = mono_defaults.uint16_class;
8787 else if (!strcmp (type_name, "long"))
8788 klass = mono_defaults.int64_class;
8789 else if (!strcmp (type_name, "ulong"))
8790 klass = mono_defaults.uint64_class;
8791 else if (!strcmp (type_name, "float"))
8792 klass = mono_defaults.single_class;
8793 else if (!strcmp (type_name, "double"))
8794 klass = mono_defaults.double_class;
8795 else if (!strcmp (type_name, "object"))
8796 klass = mono_defaults.object_class;
8797 else if (!strcmp (type_name, "obj"))
8798 klass = mono_defaults.object_class;
8799 else if (!strcmp (type_name, "string"))
8800 klass = mono_defaults.string_class;
8801 else if (!strcmp (type_name, "bool"))
8802 klass = mono_defaults.boolean_class;
8803 else if (!strcmp (type_name, "boolean"))
8804 klass = mono_defaults.boolean_class;
8806 g_error ("%s", type_name);
8807 g_assert_not_reached ();
8809 return &klass->byval_arg;
8813 * LOCKING: Take the corlib image lock.
8815 MonoMethodSignature*
8816 mono_create_icall_signature (const char *sigstr)
8821 MonoMethodSignature *res, *res2;
8822 MonoImage *corlib = mono_defaults.corlib;
8824 mono_image_lock (corlib);
8825 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8826 mono_image_unlock (corlib);
8831 parts = g_strsplit (sigstr, " ", 256);
8840 res = mono_metadata_signature_alloc (corlib, len - 1);
8845 * Under windows, the default pinvoke calling convention is STDCALL but
8848 res->call_convention = MONO_CALL_C;
8851 res->ret = type_from_typename (parts [0]);
8852 for (i = 1; i < len; ++i) {
8853 res->params [i - 1] = type_from_typename (parts [i]);
8858 mono_image_lock (corlib);
8859 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8861 res = res2; /*Value is allocated in the image pool*/
8863 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8864 mono_image_unlock (corlib);
8870 mono_find_jit_icall_by_name (const char *name)
8872 MonoJitICallInfo *info;
8873 g_assert (jit_icall_hash_name);
8876 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8877 mono_icall_unlock ();
8882 mono_find_jit_icall_by_addr (gconstpointer addr)
8884 MonoJitICallInfo *info;
8885 g_assert (jit_icall_hash_addr);
8888 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8889 mono_icall_unlock ();
8895 * mono_get_jit_icall_info:
8897 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8898 * caller should access it while holding the icall lock.
8901 mono_get_jit_icall_info (void)
8903 return jit_icall_hash_name;
8907 * mono_lookup_jit_icall_symbol:
8909 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8912 mono_lookup_jit_icall_symbol (const char *name)
8914 MonoJitICallInfo *info;
8915 const char *res = NULL;
8918 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8920 res = info->c_symbol;
8921 mono_icall_unlock ();
8926 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8929 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8930 mono_icall_unlock ();
8934 * 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
8935 * icalls without wrappers in some cases.
8938 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8940 MonoJitICallInfo *info;
8947 if (!jit_icall_hash_name) {
8948 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8949 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8952 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8953 g_warning ("jit icall already defined \"%s\"\n", name);
8954 g_assert_not_reached ();
8957 info = g_new0 (MonoJitICallInfo, 1);
8962 info->c_symbol = c_symbol;
8963 info->no_raise = no_raise;
8966 info->wrapper = func;
8968 info->wrapper = NULL;
8971 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8972 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8974 mono_icall_unlock ();
8979 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8981 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);