5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool-ms.h>
40 #include <mono/metadata/threadpool-ms-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/domain-internals.h>
56 #include <mono/metadata/metadata-internals.h>
57 #include <mono/metadata/class-internals.h>
58 #include <mono/metadata/reflection-internals.h>
59 #include <mono/metadata/marshal.h>
60 #include <mono/metadata/gc-internals.h>
61 #include <mono/metadata/mono-gc.h>
62 #include <mono/metadata/rand.h>
63 #include <mono/metadata/sysmath.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array, MonoClassField *field_handle, MonoError *error)
846 mono_error_init (error);
848 MonoClass *klass = mono_handle_class (array);
849 guint32 size = mono_array_element_size (klass);
850 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
852 const char *field_data;
854 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
855 mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type");
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 mono_error_set_argument (error, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle));
864 size *= MONO_HANDLE_GETVAL(array, max_length);
865 field_data = mono_field_get_data (field_handle);
867 if (size > mono_type_size (field_handle->type, &align)) {
868 mono_error_set_argument (error, "field_handle", "Field not large enough to fill array");
872 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
874 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
875 guint ## n *src = (guint ## n *) field_data; \
877 nEnt = (size / sizeof(guint ## n)); \
879 for (i = 0; i < nEnt; i++) { \
880 data[i] = read ## n (&src[i]); \
884 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
886 switch (type->type) {
903 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
907 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
912 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
914 return offsetof (MonoString, chars);
917 ICALL_EXPORT MonoObject *
918 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
920 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
924 MonoObject *ret = mono_object_clone_checked (obj, &error);
925 mono_error_set_pending_exception (&error);
932 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
938 MONO_CHECK_ARG_NULL (handle,);
940 klass = mono_class_from_mono_type (handle);
941 MONO_CHECK_ARG (handle, klass,);
943 if (mono_class_is_gtd (klass))
946 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
947 if (!is_ok (&error)) {
948 mono_error_set_pending_exception (&error);
952 /* This will call the type constructor */
953 if (!mono_runtime_class_init_full (vtable, &error))
954 mono_error_set_pending_exception (&error);
958 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
962 mono_image_check_for_module_cctor (image);
963 if (image->has_module_cctor) {
964 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
965 if (!mono_error_ok (&error)) {
966 mono_error_set_pending_exception (&error);
969 /*It's fine to raise the exception here*/
970 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
971 if (!is_ok (&error)) {
972 mono_error_set_pending_exception (&error);
975 if (!mono_runtime_class_init_full (vtable, &error))
976 mono_error_set_pending_exception (&error);
980 ICALL_EXPORT MonoBoolean
981 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
983 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
984 // It does not work on win32
990 MonoInternalThread *thread;
992 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
993 /* if we have no info we are optimistic and assume there is enough room */
997 thread = mono_thread_internal_current ();
998 // .net seems to check that at least 50% of stack is available
999 min_size = thread->stack_size / 2;
1001 // TODO: It's not always set
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionType *
1216 ves_icall_System_Object_GetType (MonoObject *obj)
1219 MonoReflectionType *ret;
1220 #ifndef DISABLE_REMOTING
1221 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1222 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1225 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1227 mono_error_set_pending_exception (&error);
1232 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1234 MonoMethod **dest = (MonoMethod **)data;
1236 /* skip unmanaged frames */
1241 if (!strcmp (m->klass->name_space, "System.Reflection"))
1250 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1252 MonoMethod **dest = (MonoMethod **)data;
1254 /* skip unmanaged frames */
1258 if (m->wrapper_type != MONO_WRAPPER_NONE)
1266 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1277 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1279 MonoMethod **dest = (MonoMethod **)data;
1281 /* skip unmanaged frames */
1285 if (m->wrapper_type != MONO_WRAPPER_NONE)
1293 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1294 || (!strcmp (m->klass->name_space, "System"))))
1304 static MonoReflectionType *
1305 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1307 MonoMethod *m, *dest;
1309 MonoType *type = NULL;
1310 MonoAssembly *assembly = NULL;
1311 gboolean type_resolve = FALSE;
1312 MonoImage *rootimage = NULL;
1314 mono_error_init (error);
1317 * We must compute the calling assembly as type loading must happen under a metadata context.
1318 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1319 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1321 m = mono_method_get_last_managed ();
1323 if (m && m->klass->image != mono_defaults.corlib) {
1324 /* Happens with inlining */
1326 /* Ugly hack: type_from_parsed_name is called from
1327 * System.Type.internal_from_name, which is called most
1328 * directly from System.Type.GetType(string,bool,bool) but
1329 * also indirectly from places such as
1330 * System.Type.GetType(string,func,func) (via
1331 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1332 * so we need to skip over all of those to find the true caller.
1334 * It would be nice if we had stack marks.
1336 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1342 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1343 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1344 * to crash. This only seems to happen in some strange remoting
1345 * scenarios and I was unable to figure out what's happening there.
1346 * Dec 10, 2005 - Martin.
1350 assembly = dest->klass->image->assembly;
1351 type_resolve = TRUE;
1352 rootimage = assembly->image;
1354 g_warning (G_STRLOC);
1356 *caller_assembly = assembly;
1358 if (info->assembly.name)
1359 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1362 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1363 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1364 return_val_if_nok (error, NULL);
1368 // Say we're looking for System.Generic.Dict<int, Local>
1369 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1370 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1371 // is messed up when we go to construct the Local as the type arg...
1373 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1374 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1375 if (!info->assembly.name && !type) {
1377 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1378 return_val_if_nok (error, NULL);
1380 if (assembly && !type && type_resolve) {
1381 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1382 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1383 return_val_if_nok (error, NULL);
1389 return mono_type_get_object_checked (mono_domain_get (), type, error);
1392 ICALL_EXPORT MonoReflectionType*
1393 ves_icall_System_Type_internal_from_name (MonoString *name,
1394 MonoBoolean throwOnError,
1395 MonoBoolean ignoreCase)
1398 MonoTypeNameParse info;
1399 MonoReflectionType *type = NULL;
1401 MonoAssembly *caller_assembly;
1403 char *str = mono_string_to_utf8_checked (name, &error);
1404 if (!is_ok (&error))
1407 parsedOk = mono_reflection_parse_type (str, &info);
1409 /* mono_reflection_parse_type() mangles the string */
1411 mono_reflection_free_type_info (&info);
1413 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1417 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1419 if (!is_ok (&error)) {
1420 mono_reflection_free_type_info (&info);
1426 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1428 if (info.assembly.name)
1429 aname = mono_stringify_assembly_name (&info.assembly);
1430 else if (caller_assembly)
1431 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1433 aname = g_strdup ("");
1434 mono_error_set_type_load_name (&error, tname, aname, "");
1436 mono_reflection_free_type_info (&info);
1442 if (!is_ok (&error)) {
1444 mono_error_set_pending_exception (&error);
1446 mono_error_cleanup (&error);
1454 ICALL_EXPORT MonoReflectionType*
1455 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1458 MonoReflectionType *ret;
1459 MonoDomain *domain = mono_domain_get ();
1461 ret = mono_type_get_object_checked (domain, handle, &error);
1462 mono_error_set_pending_exception (&error);
1467 ICALL_EXPORT MonoType*
1468 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1470 return mono_class_get_type (klass);
1474 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1476 g_ptr_array_free (ptr_array, TRUE);
1480 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1486 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1489 char *res = mono_string_to_utf8_checked (s, &error);
1490 mono_error_set_pending_exception (&error);
1494 /* System.TypeCode */
1513 TYPECODE_STRING = 18
1516 ICALL_EXPORT guint32
1517 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1519 int t = type->type->type;
1521 if (type->type->byref)
1522 return TYPECODE_OBJECT;
1526 case MONO_TYPE_VOID:
1527 return TYPECODE_OBJECT;
1528 case MONO_TYPE_BOOLEAN:
1529 return TYPECODE_BOOLEAN;
1531 return TYPECODE_BYTE;
1533 return TYPECODE_SBYTE;
1535 return TYPECODE_UINT16;
1537 return TYPECODE_INT16;
1538 case MONO_TYPE_CHAR:
1539 return TYPECODE_CHAR;
1543 return TYPECODE_OBJECT;
1545 return TYPECODE_UINT32;
1547 return TYPECODE_INT32;
1549 return TYPECODE_UINT64;
1551 return TYPECODE_INT64;
1553 return TYPECODE_SINGLE;
1555 return TYPECODE_DOUBLE;
1556 case MONO_TYPE_VALUETYPE: {
1557 MonoClass *klass = type->type->data.klass;
1559 if (klass->enumtype) {
1560 t = mono_class_enum_basetype (klass)->type;
1562 } else if (mono_is_corlib_image (klass->image)) {
1563 if (strcmp (klass->name_space, "System") == 0) {
1564 if (strcmp (klass->name, "Decimal") == 0)
1565 return TYPECODE_DECIMAL;
1566 else if (strcmp (klass->name, "DateTime") == 0)
1567 return TYPECODE_DATETIME;
1570 return TYPECODE_OBJECT;
1572 case MONO_TYPE_STRING:
1573 return TYPECODE_STRING;
1574 case MONO_TYPE_SZARRAY:
1575 case MONO_TYPE_ARRAY:
1576 case MONO_TYPE_OBJECT:
1578 case MONO_TYPE_MVAR:
1579 case MONO_TYPE_TYPEDBYREF:
1580 return TYPECODE_OBJECT;
1581 case MONO_TYPE_CLASS:
1583 MonoClass *klass = type->type->data.klass;
1584 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1585 if (strcmp (klass->name, "DBNull") == 0)
1586 return TYPECODE_DBNULL;
1589 return TYPECODE_OBJECT;
1590 case MONO_TYPE_GENERICINST:
1591 return TYPECODE_OBJECT;
1593 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1599 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1601 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1602 return mono_class_enum_basetype (type->data.klass);
1603 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1604 return mono_class_enum_basetype (type->data.generic_class->container_class);
1608 ICALL_EXPORT guint32
1609 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1614 g_assert (type != NULL);
1616 klass = mono_class_from_mono_type (type->type);
1617 klassc = mono_class_from_mono_type (c->type);
1619 if (type->type->byref ^ c->type->byref)
1622 if (type->type->byref) {
1623 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1624 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1626 klass = mono_class_from_mono_type (t);
1627 klassc = mono_class_from_mono_type (ot);
1629 if (mono_type_is_primitive (t)) {
1630 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1631 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1632 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1633 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1634 return t->type == ot->type;
1636 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1639 if (klass->valuetype)
1640 return klass == klassc;
1641 return klass->valuetype == klassc->valuetype;
1644 return mono_class_is_assignable_from (klass, klassc);
1647 ICALL_EXPORT guint32
1648 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1651 MonoClass *klass = mono_class_from_mono_type (type->type);
1652 mono_class_init_checked (klass, &error);
1653 if (!is_ok (&error)) {
1654 mono_error_set_pending_exception (&error);
1657 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1658 mono_error_set_pending_exception (&error);
1662 ICALL_EXPORT guint32
1663 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1665 MonoClass *klass = mono_class_from_mono_type (type->type);
1666 return mono_class_get_flags (klass);
1669 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1670 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1673 MonoClass *klass = field->field->parent;
1674 MonoMarshalType *info;
1678 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1679 if (mono_class_is_gtd (klass) ||
1680 (gklass && gklass->context.class_inst->is_open))
1683 ftype = mono_field_get_type (field->field);
1684 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1687 info = mono_marshal_load_type_info (klass);
1689 for (i = 0; i < info->num_fields; ++i) {
1690 if (info->fields [i].field == field->field) {
1691 if (!info->fields [i].mspec)
1694 MonoReflectionMarshalAsAttribute* obj;
1695 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1696 if (!mono_error_ok (&error))
1697 mono_error_set_pending_exception (&error);
1706 ICALL_EXPORT MonoReflectionField*
1707 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1710 gboolean found = FALSE;
1716 klass = handle->parent;
1718 klass = mono_class_from_mono_type (type);
1720 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1723 /* The managed code will throw the exception */
1727 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1728 mono_error_set_pending_exception (&error);
1732 ICALL_EXPORT MonoReflectionEvent*
1733 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1741 klass = handle->parent;
1743 klass = mono_class_from_mono_type (type);
1745 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1747 /* Managed code will throw an exception */
1751 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1752 mono_error_set_pending_exception (&error);
1757 ICALL_EXPORT MonoReflectionProperty*
1758 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1766 klass = handle->parent;
1768 klass = mono_class_from_mono_type (type);
1770 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1772 /* Managed code will throw an exception */
1776 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1777 mono_error_set_pending_exception (&error);
1781 ICALL_EXPORT MonoArray*
1782 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1785 MonoType *type = mono_field_get_type_checked (field->field, &error);
1788 if (!mono_error_ok (&error)) {
1789 mono_error_set_pending_exception (&error);
1793 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1794 mono_error_set_pending_exception (&error);
1799 vell_icall_get_method_attributes (MonoMethod *method)
1801 return method->flags;
1805 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1808 MonoReflectionType *rt;
1809 MonoDomain *domain = mono_domain_get ();
1810 MonoMethodSignature* sig;
1812 sig = mono_method_signature_checked (method, &error);
1813 if (!mono_error_ok (&error)) {
1814 mono_error_set_pending_exception (&error);
1818 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1819 if (!mono_error_ok (&error)) {
1820 mono_error_set_pending_exception (&error);
1824 MONO_STRUCT_SETREF (info, parent, rt);
1826 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1827 if (!mono_error_ok (&error)) {
1828 mono_error_set_pending_exception (&error);
1832 MONO_STRUCT_SETREF (info, ret, rt);
1834 info->attrs = method->flags;
1835 info->implattrs = method->iflags;
1836 if (sig->call_convention == MONO_CALL_DEFAULT)
1837 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1839 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1844 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1847 ICALL_EXPORT MonoArray*
1848 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1851 MonoDomain *domain = mono_domain_get ();
1853 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1854 mono_error_set_pending_exception (&error);
1858 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1859 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1862 MonoDomain *domain = mono_domain_get ();
1863 MonoReflectionMarshalAsAttribute* res = NULL;
1864 MonoMarshalSpec **mspecs;
1867 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1868 mono_method_get_marshal_info (method, mspecs);
1871 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1872 if (!mono_error_ok (&error)) {
1873 mono_error_set_pending_exception (&error);
1878 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1880 mono_metadata_free_marshal_spec (mspecs [i]);
1887 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1889 MonoClass *parent = field->field->parent;
1890 mono_class_setup_fields (parent);
1892 return field->field->offset - sizeof (MonoObject);
1895 ICALL_EXPORT MonoReflectionType*
1896 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1899 MonoReflectionType *ret;
1902 parent = declaring? field->field->parent: field->klass;
1904 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1905 mono_error_set_pending_exception (&error);
1911 ICALL_EXPORT MonoObject *
1912 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1915 MonoClass *fklass = field->klass;
1916 MonoClassField *cf = field->field;
1917 MonoDomain *domain = mono_object_domain (field);
1919 if (fklass->image->assembly->ref_only) {
1920 mono_set_pending_exception (mono_get_exception_invalid_operation (
1921 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1925 if (mono_security_core_clr_enabled () &&
1926 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1927 mono_error_set_pending_exception (&error);
1931 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1932 mono_error_set_pending_exception (&error);
1937 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1940 MonoClassField *cf = field->field;
1944 if (field->klass->image->assembly->ref_only) {
1945 mono_set_pending_exception (mono_get_exception_invalid_operation (
1946 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1950 if (mono_security_core_clr_enabled () &&
1951 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1952 mono_error_set_pending_exception (&error);
1956 type = mono_field_get_type_checked (cf, &error);
1957 if (!mono_error_ok (&error)) {
1958 mono_error_set_pending_exception (&error);
1962 v = (gchar *) value;
1964 switch (type->type) {
1967 case MONO_TYPE_BOOLEAN:
1970 case MONO_TYPE_CHAR:
1979 case MONO_TYPE_VALUETYPE:
1982 v += sizeof (MonoObject);
1984 case MONO_TYPE_STRING:
1985 case MONO_TYPE_OBJECT:
1986 case MONO_TYPE_CLASS:
1987 case MONO_TYPE_ARRAY:
1988 case MONO_TYPE_SZARRAY:
1991 case MONO_TYPE_GENERICINST: {
1992 MonoGenericClass *gclass = type->data.generic_class;
1993 g_assert (!gclass->context.class_inst->is_open);
1995 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1996 MonoClass *nklass = mono_class_from_mono_type (type);
1997 MonoObject *nullable;
2000 * Convert the boxed vtype into a Nullable structure.
2001 * This is complicated by the fact that Nullables have
2002 * a variable structure.
2004 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2005 if (!mono_error_ok (&error)) {
2006 mono_error_set_pending_exception (&error);
2010 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2012 v = (gchar *)mono_object_unbox (nullable);
2015 if (gclass->container_class->valuetype && (v != NULL))
2016 v += sizeof (MonoObject);
2020 g_error ("type 0x%x not handled in "
2021 "ves_icall_FieldInfo_SetValueInternal", type->type);
2026 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2027 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2028 if (!is_ok (&error)) {
2029 mono_error_set_pending_exception (&error);
2032 if (!vtable->initialized) {
2033 if (!mono_runtime_class_init_full (vtable, &error)) {
2034 mono_error_set_pending_exception (&error);
2038 mono_field_static_set_value (vtable, cf, v);
2040 mono_field_set_value (obj, cf, v);
2045 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2054 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2055 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2059 if (MONO_TYPE_IS_REFERENCE (f->type))
2060 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2062 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2065 ICALL_EXPORT MonoObject *
2066 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2068 MonoObject *o = NULL;
2069 MonoClassField *field = rfield->field;
2071 MonoDomain *domain = mono_object_domain (rfield);
2073 MonoTypeEnum def_type;
2074 const char *def_value;
2078 mono_class_init (field->parent);
2080 t = mono_field_get_type_checked (field, &error);
2081 if (!mono_error_ok (&error)) {
2082 mono_error_set_pending_exception (&error);
2086 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2087 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2091 if (image_is_dynamic (field->parent->image)) {
2092 MonoClass *klass = field->parent;
2093 int fidx = field - klass->fields;
2094 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2096 g_assert (def_values);
2097 def_type = def_values [fidx].def_type;
2098 def_value = def_values [fidx].data;
2100 if (def_type == MONO_TYPE_END) {
2101 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2105 def_value = mono_class_get_field_default_value (field, &def_type);
2106 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2108 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2113 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2117 case MONO_TYPE_BOOLEAN:
2120 case MONO_TYPE_CHAR:
2128 case MONO_TYPE_R8: {
2131 /* boxed value type */
2132 t = g_new0 (MonoType, 1);
2134 klass = mono_class_from_mono_type (t);
2136 o = mono_object_new_checked (domain, klass, &error);
2137 if (!mono_error_ok (&error)) {
2138 mono_error_set_pending_exception (&error);
2141 v = ((gchar *) o) + sizeof (MonoObject);
2142 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2143 if (mono_error_set_pending_exception (&error))
2147 case MONO_TYPE_STRING:
2148 case MONO_TYPE_CLASS:
2149 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2150 if (mono_error_set_pending_exception (&error))
2154 g_assert_not_reached ();
2160 ICALL_EXPORT MonoReflectionType*
2161 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2164 MonoReflectionType *ret;
2167 type = mono_field_get_type_checked (ref_field->field, &error);
2168 if (!mono_error_ok (&error)) {
2169 mono_error_set_pending_exception (&error);
2173 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2174 if (!mono_error_ok (&error)) {
2175 mono_error_set_pending_exception (&error);
2182 /* From MonoProperty.cs */
2184 PInfo_Attributes = 1,
2185 PInfo_GetMethod = 1 << 1,
2186 PInfo_SetMethod = 1 << 2,
2187 PInfo_ReflectedType = 1 << 3,
2188 PInfo_DeclaringType = 1 << 4,
2193 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2196 MonoReflectionType *rt;
2197 MonoReflectionMethod *rm;
2198 MonoDomain *domain = mono_object_domain (property);
2199 const MonoProperty *pproperty = property->property;
2201 if ((req_info & PInfo_ReflectedType) != 0) {
2202 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2203 if (mono_error_set_pending_exception (&error))
2206 MONO_STRUCT_SETREF (info, parent, rt);
2208 if ((req_info & PInfo_DeclaringType) != 0) {
2209 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2210 if (mono_error_set_pending_exception (&error))
2213 MONO_STRUCT_SETREF (info, declaring_type, rt);
2216 if ((req_info & PInfo_Name) != 0)
2217 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2219 if ((req_info & PInfo_Attributes) != 0)
2220 info->attrs = pproperty->attrs;
2222 if ((req_info & PInfo_GetMethod) != 0) {
2223 if (pproperty->get &&
2224 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2225 pproperty->get->klass == property->klass)) {
2226 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2227 if (mono_error_set_pending_exception (&error))
2233 MONO_STRUCT_SETREF (info, get, rm);
2235 if ((req_info & PInfo_SetMethod) != 0) {
2236 if (pproperty->set &&
2237 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2238 pproperty->set->klass == property->klass)) {
2239 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2240 if (mono_error_set_pending_exception (&error))
2246 MONO_STRUCT_SETREF (info, set, rm);
2249 * There may be other methods defined for properties, though, it seems they are not exposed
2250 * in the reflection API
2255 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2258 MonoReflectionType *rt;
2259 MonoReflectionMethod *rm;
2260 MonoDomain *domain = mono_object_domain (event);
2262 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2263 if (mono_error_set_pending_exception (&error))
2266 MONO_STRUCT_SETREF (info, reflected_type, rt);
2268 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2269 if (mono_error_set_pending_exception (&error))
2272 MONO_STRUCT_SETREF (info, declaring_type, rt);
2274 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2275 info->attrs = event->event->attrs;
2277 if (event->event->add) {
2278 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2279 if (mono_error_set_pending_exception (&error))
2285 MONO_STRUCT_SETREF (info, add_method, rm);
2287 if (event->event->remove) {
2288 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2289 if (mono_error_set_pending_exception (&error))
2295 MONO_STRUCT_SETREF (info, remove_method, rm);
2297 if (event->event->raise) {
2298 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2299 if (mono_error_set_pending_exception (&error))
2305 MONO_STRUCT_SETREF (info, raise_method, rm);
2307 #ifndef MONO_SMALL_CONFIG
2308 if (event->event->other) {
2310 while (event->event->other [n])
2312 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2313 if (mono_error_set_pending_exception (&error))
2315 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2317 for (i = 0; i < n; i++) {
2318 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2319 if (mono_error_set_pending_exception (&error))
2321 mono_array_setref (info->other_methods, i, rm);
2328 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2333 mono_class_setup_interfaces (klass, error);
2334 if (!mono_error_ok (error))
2337 for (i = 0; i < klass->interface_count; i++) {
2338 ic = klass->interfaces [i];
2339 g_hash_table_insert (ifaces, ic, ic);
2341 collect_interfaces (ic, ifaces, error);
2342 if (!mono_error_ok (error))
2348 MonoArray *iface_array;
2349 MonoGenericContext *context;
2353 } FillIfaceArrayData;
2356 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2358 MonoReflectionType *rt;
2359 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2360 MonoClass *ic = (MonoClass *)key;
2361 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2363 if (!mono_error_ok (data->error))
2366 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2367 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2368 if (!mono_error_ok (data->error))
2372 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2373 if (!mono_error_ok (data->error))
2376 mono_array_setref (data->iface_array, data->next_idx++, rt);
2379 mono_metadata_free_type (inflated);
2383 get_interfaces_hash (gconstpointer v1)
2385 MonoClass *k = (MonoClass*)v1;
2387 return k->type_token;
2390 ICALL_EXPORT MonoArray*
2391 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2394 MonoClass *klass = mono_class_from_mono_type (type->type);
2396 FillIfaceArrayData data = { 0 };
2399 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2401 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2402 data.context = mono_class_get_context (klass);
2403 klass = mono_class_get_generic_class (klass)->container_class;
2406 for (parent = klass; parent; parent = parent->parent) {
2407 mono_class_setup_interfaces (parent, &error);
2408 if (!mono_error_ok (&error))
2410 collect_interfaces (parent, iface_hash, &error);
2411 if (!mono_error_ok (&error))
2415 data.error = &error;
2416 data.domain = mono_object_domain (type);
2418 len = g_hash_table_size (iface_hash);
2420 g_hash_table_destroy (iface_hash);
2421 if (!data.domain->empty_types) {
2422 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2423 if (!is_ok (&error))
2426 return data.domain->empty_types;
2429 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2430 if (!is_ok (&error))
2432 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2433 if (!mono_error_ok (&error))
2436 g_hash_table_destroy (iface_hash);
2437 return data.iface_array;
2440 g_hash_table_destroy (iface_hash);
2441 mono_error_set_pending_exception (&error);
2446 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2448 gboolean variance_used;
2449 MonoClass *klass = mono_class_from_mono_type (type->type);
2450 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2451 MonoReflectionMethod *member;
2454 int i = 0, len, ioffset;
2458 mono_class_init_checked (klass, &error);
2459 if (mono_error_set_pending_exception (&error))
2461 mono_class_init_checked (iclass, &error);
2462 if (mono_error_set_pending_exception (&error))
2465 mono_class_setup_vtable (klass);
2467 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2471 len = mono_class_num_methods (iclass);
2472 domain = mono_object_domain (type);
2473 MonoArray *targets_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 (targets, (MonoObject*) targets_arr);
2477 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2478 if (mono_error_set_pending_exception (&error))
2480 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2482 while ((method = mono_class_get_methods (iclass, &iter))) {
2483 member = mono_method_get_object_checked (domain, method, iclass, &error);
2484 if (mono_error_set_pending_exception (&error))
2486 mono_array_setref (*methods, i, member);
2487 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2488 if (mono_error_set_pending_exception (&error))
2490 mono_array_setref (*targets, i, member);
2497 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2500 MonoClass *klass = mono_class_from_mono_type (type->type);
2502 mono_class_init_checked (klass, &error);
2503 if (mono_error_set_pending_exception (&error))
2506 if (image_is_dynamic (klass->image)) {
2507 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2508 *packing = tb->packing_size;
2509 *size = tb->class_size;
2511 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2515 ICALL_EXPORT MonoReflectionType*
2516 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2519 MonoReflectionType *ret;
2522 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2523 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2524 mono_error_set_pending_exception (&error);
2528 klass = mono_class_from_mono_type (type->type);
2529 mono_class_init_checked (klass, &error);
2530 if (mono_error_set_pending_exception (&error))
2534 // GetElementType should only return a type for:
2535 // Array Pointer PassedByRef
2536 if (type->type->byref)
2537 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2538 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2539 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2540 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2541 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2545 mono_error_set_pending_exception (&error);
2550 ICALL_EXPORT MonoReflectionType*
2551 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2554 MonoReflectionType *ret;
2556 if (type->type->byref)
2559 MonoClass *klass = mono_class_from_mono_type (type->type);
2563 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2564 mono_error_set_pending_exception (&error);
2569 ICALL_EXPORT MonoBoolean
2570 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2572 return type->type->type == MONO_TYPE_PTR;
2575 ICALL_EXPORT MonoBoolean
2576 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2578 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)));
2581 ICALL_EXPORT MonoBoolean
2582 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2584 return type->type->byref;
2587 ICALL_EXPORT MonoBoolean
2588 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2591 MonoClass *klass = mono_class_from_mono_type (type->type);
2592 mono_class_init_checked (klass, &error);
2593 if (mono_error_set_pending_exception (&error))
2596 return mono_class_is_com_object (klass);
2599 ICALL_EXPORT guint32
2600 ves_icall_reflection_get_token (MonoObject* obj)
2603 guint32 result = mono_reflection_get_token_checked (obj, &error);
2604 mono_error_set_pending_exception (&error);
2608 ICALL_EXPORT MonoReflectionModuleHandle
2609 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2611 mono_error_init (error);
2612 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2613 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2614 MonoClass *klass = mono_class_from_mono_type (t);
2615 return mono_module_get_object_handle (domain, klass->image, error);
2618 ICALL_EXPORT MonoReflectionAssembly*
2619 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2622 MonoDomain *domain = mono_domain_get ();
2623 MonoClass *klass = mono_class_from_mono_type (type->type);
2624 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2625 mono_error_set_pending_exception (&error);
2629 ICALL_EXPORT MonoReflectionType*
2630 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2633 MonoReflectionType *ret;
2634 MonoDomain *domain = mono_domain_get ();
2637 if (type->type->byref)
2639 if (type->type->type == MONO_TYPE_VAR) {
2640 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2641 klass = param ? param->owner.klass : NULL;
2642 } else if (type->type->type == MONO_TYPE_MVAR) {
2643 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2644 klass = param ? param->owner.method->klass : NULL;
2646 klass = mono_class_from_mono_type (type->type)->nested_in;
2652 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2653 mono_error_set_pending_exception (&error);
2658 ICALL_EXPORT MonoStringHandle
2659 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2661 MonoDomain *domain = mono_domain_get ();
2662 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2663 MonoClass *klass = mono_class_from_mono_type (type);
2666 char *n = g_strdup_printf ("%s&", klass->name);
2667 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2673 return mono_string_new_handle (domain, klass->name, error);
2677 ICALL_EXPORT MonoStringHandle
2678 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2680 MonoDomain *domain = mono_domain_get ();
2681 MonoClass *klass = mono_class_from_mono_type_handle (type);
2683 while (klass->nested_in)
2684 klass = klass->nested_in;
2686 if (klass->name_space [0] == '\0')
2687 return NULL_HANDLE_STRING;
2689 return mono_string_new_handle (domain, klass->name_space, error);
2693 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2697 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2698 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2702 klass = mono_class_from_mono_type (type->type);
2708 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2710 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2713 ICALL_EXPORT MonoArray*
2714 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2717 MonoReflectionType *rt;
2719 MonoClass *klass, *pklass;
2720 MonoDomain *domain = mono_object_domain (type);
2723 klass = mono_class_from_mono_type (type->type);
2725 if (mono_class_is_gtd (klass)) {
2726 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2727 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2728 if (mono_error_set_pending_exception (&error))
2730 for (i = 0; i < container->type_argc; ++i) {
2731 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2733 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2734 if (mono_error_set_pending_exception (&error))
2737 mono_array_setref (res, i, rt);
2739 } else if (mono_class_is_ginst (klass)) {
2740 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2741 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2742 if (mono_error_set_pending_exception (&error))
2744 for (i = 0; i < inst->type_argc; ++i) {
2745 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2746 if (mono_error_set_pending_exception (&error))
2749 mono_array_setref (res, i, rt);
2757 ICALL_EXPORT gboolean
2758 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2762 if (!IS_MONOTYPE (type))
2765 if (type->type->byref)
2768 klass = mono_class_from_mono_type (type->type);
2769 return mono_class_is_gtd (klass);
2772 ICALL_EXPORT MonoReflectionType*
2773 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2776 MonoReflectionType *ret;
2779 if (type->type->byref)
2782 klass = mono_class_from_mono_type (type->type);
2784 if (mono_class_is_gtd (klass)) {
2785 return type; /* check this one */
2787 if (mono_class_is_ginst (klass)) {
2788 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2791 tb = mono_class_get_ref_info (generic_class);
2793 if (generic_class->wastypebuilder && tb)
2794 return (MonoReflectionType *)tb;
2796 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2797 mono_error_set_pending_exception (&error);
2805 ICALL_EXPORT MonoReflectionType*
2806 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2809 MonoReflectionType *ret;
2811 MonoType *geninst, **types;
2814 g_assert (IS_MONOTYPE (type));
2815 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2816 if (mono_error_set_pending_exception (&error))
2819 count = mono_array_length (type_array);
2820 types = g_new0 (MonoType *, count);
2822 for (i = 0; i < count; i++) {
2823 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2824 types [i] = t->type;
2827 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2830 mono_error_set_pending_exception (&error);
2834 klass = mono_class_from_mono_type (geninst);
2836 /*we might inflate to the GTD*/
2837 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2838 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2842 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2843 mono_error_set_pending_exception (&error);
2848 ICALL_EXPORT gboolean
2849 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2853 if (!IS_MONOTYPE (type))
2856 if (type->type->byref)
2859 klass = mono_class_from_mono_type (type->type);
2860 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2864 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2866 if (!IS_MONOTYPE (type))
2869 if (is_generic_parameter (type->type))
2870 return mono_type_get_generic_param_num (type->type);
2874 ICALL_EXPORT MonoGenericParamInfo *
2875 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2877 return mono_generic_param_info (type->type->data.generic_param);
2880 ICALL_EXPORT MonoBoolean
2881 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2883 return is_generic_parameter (type->type);
2886 ICALL_EXPORT MonoReflectionMethod*
2887 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2888 MonoReflectionMethod* generic)
2895 MonoReflectionMethod *ret = NULL;
2897 domain = ((MonoObject *)type)->vtable->domain;
2899 klass = mono_class_from_mono_type (type->type);
2900 mono_class_init_checked (klass, &error);
2901 if (mono_error_set_pending_exception (&error))
2905 while ((method = mono_class_get_methods (klass, &iter))) {
2906 if (method->token == generic->method->token) {
2907 ret = mono_method_get_object_checked (domain, method, klass, &error);
2908 if (mono_error_set_pending_exception (&error))
2916 ICALL_EXPORT MonoReflectionMethod *
2917 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2920 MonoType *type = ref_type->type;
2922 MonoReflectionMethod *ret = NULL;
2924 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2925 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2928 if (type->type == MONO_TYPE_VAR)
2931 method = mono_type_get_generic_param_owner (type)->owner.method;
2934 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2935 if (!mono_error_ok (&error))
2936 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2940 ICALL_EXPORT MonoBoolean
2941 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2943 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2947 ICALL_EXPORT MonoBoolean
2948 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2950 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2955 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2957 MonoDomain *domain = mono_domain_get ();
2958 MonoImage *image = method->method->klass->image;
2959 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2960 MonoTableInfo *tables = image->tables;
2961 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2962 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2963 guint32 im_cols [MONO_IMPLMAP_SIZE];
2964 guint32 scope_token;
2965 const char *import = NULL;
2966 const char *scope = NULL;
2968 if (image_is_dynamic (image)) {
2969 MonoReflectionMethodAux *method_aux =
2970 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2972 import = method_aux->dllentry;
2973 scope = method_aux->dll;
2976 if (!import || !scope) {
2977 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2982 if (piinfo->implmap_idx) {
2983 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2985 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2986 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2987 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2988 scope = mono_metadata_string_heap (image, scope_token);
2992 *flags = piinfo->piflags;
2993 *entry_point = mono_string_new (domain, import);
2994 *dll_name = mono_string_new (domain, scope);
2997 ICALL_EXPORT MonoReflectionMethod *
2998 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3000 MonoMethodInflated *imethod;
3002 MonoReflectionMethod *ret = NULL;
3005 if (method->method->is_generic)
3008 if (!method->method->is_inflated)
3011 imethod = (MonoMethodInflated *) method->method;
3013 result = imethod->declaring;
3014 /* Not a generic method. */
3015 if (!result->is_generic)
3018 if (image_is_dynamic (method->method->klass->image)) {
3019 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3020 MonoReflectionMethod *res;
3023 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3024 * the dynamic case as well ?
3026 mono_image_lock ((MonoImage*)image);
3027 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3028 mono_image_unlock ((MonoImage*)image);
3034 if (imethod->context.class_inst) {
3035 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3036 /*Generic methods gets the context of the GTD.*/
3037 if (mono_class_get_context (klass)) {
3038 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3039 if (!mono_error_ok (&error))
3044 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3046 if (!mono_error_ok (&error))
3047 mono_error_set_pending_exception (&error);
3051 ICALL_EXPORT gboolean
3052 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3054 return mono_method_signature (method->method)->generic_param_count != 0;
3057 ICALL_EXPORT gboolean
3058 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3060 return method->method->is_generic;
3063 ICALL_EXPORT MonoArray*
3064 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3067 MonoReflectionType *rt;
3072 domain = mono_object_domain (method);
3074 if (method->method->is_inflated) {
3075 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3078 count = inst->type_argc;
3079 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3080 if (mono_error_set_pending_exception (&error))
3083 for (i = 0; i < count; i++) {
3084 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3085 if (mono_error_set_pending_exception (&error))
3088 mono_array_setref (res, i, rt);
3095 count = mono_method_signature (method->method)->generic_param_count;
3096 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3097 if (mono_error_set_pending_exception (&error))
3100 for (i = 0; i < count; i++) {
3101 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3102 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3103 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3105 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3106 if (mono_error_set_pending_exception (&error))
3109 mono_array_setref (res, i, rt);
3115 ICALL_EXPORT MonoObject *
3116 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3120 * Invoke from reflection is supposed to always be a virtual call (the API
3121 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3122 * greater flexibility.
3124 MonoMethod *m = method->method;
3125 MonoMethodSignature *sig = mono_method_signature (m);
3128 void *obj = this_arg;
3132 if (mono_security_core_clr_enabled () &&
3133 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3134 mono_error_set_pending_exception (&error);
3138 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3139 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3140 mono_error_cleanup (&error); /* FIXME does this make sense? */
3141 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3146 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3147 if (!is_ok (&error)) {
3148 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3151 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3152 char *target_name = mono_type_get_full_name (m->klass);
3153 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3154 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3156 g_free (target_name);
3160 m = mono_object_get_virtual_method (this_arg, m);
3161 /* must pass the pointer to the value for valuetype methods */
3162 if (m->klass->valuetype)
3163 obj = mono_object_unbox (this_arg);
3164 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3165 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3170 if (sig->ret->byref) {
3171 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"));
3175 pcount = params? mono_array_length (params): 0;
3176 if (pcount != sig->param_count) {
3177 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3181 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3182 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."));
3186 image = m->klass->image;
3187 if (image->assembly->ref_only) {
3188 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."));
3192 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3193 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3197 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3201 intptr_t *lower_bounds;
3202 pcount = mono_array_length (params);
3203 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3204 /* Note: the synthetized array .ctors have int32 as argument type */
3205 for (i = 0; i < pcount; ++i)
3206 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3208 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3209 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3210 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3211 if (!mono_error_ok (&error)) {
3212 mono_error_set_pending_exception (&error);
3216 for (i = 0; i < mono_array_length (arr); ++i) {
3217 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3218 if (!mono_error_ok (&error)) {
3219 mono_error_set_pending_exception (&error);
3222 mono_array_setref_fast (arr, i, subarray);
3224 return (MonoObject*)arr;
3227 if (m->klass->rank == pcount) {
3228 /* Only lengths provided. */
3229 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3230 if (!mono_error_ok (&error)) {
3231 mono_error_set_pending_exception (&error);
3235 return (MonoObject*)arr;
3237 g_assert (pcount == (m->klass->rank * 2));
3238 /* The arguments are lower-bound-length pairs */
3239 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3241 for (i = 0; i < pcount / 2; ++i) {
3242 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3243 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3246 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3247 if (!mono_error_ok (&error)) {
3248 mono_error_set_pending_exception (&error);
3252 return (MonoObject*)arr;
3255 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3256 mono_error_set_pending_exception (&error);
3260 #ifndef DISABLE_REMOTING
3261 ICALL_EXPORT MonoObject *
3262 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3265 MonoDomain *domain = mono_object_domain (method);
3266 MonoMethod *m = method->method;
3267 MonoMethodSignature *sig = mono_method_signature (m);
3268 MonoArray *out_args;
3270 int i, j, outarg_count = 0;
3272 if (m->klass == mono_defaults.object_class) {
3273 if (!strcmp (m->name, "FieldGetter")) {
3274 MonoClass *k = this_arg->vtable->klass;
3278 /* If this is a proxy, then it must be a CBO */
3279 if (k == mono_defaults.transparent_proxy_class) {
3280 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3281 this_arg = tp->rp->unwrapped_server;
3282 g_assert (this_arg);
3283 k = this_arg->vtable->klass;
3286 name = mono_array_get (params, MonoString *, 1);
3287 str = mono_string_to_utf8_checked (name, &error);
3288 if (mono_error_set_pending_exception (&error))
3292 MonoClassField* field = mono_class_get_field_from_name (k, str);
3295 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3296 if (field_klass->valuetype) {
3297 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3298 if (mono_error_set_pending_exception (&error))
3301 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3303 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3304 if (mono_error_set_pending_exception (&error))
3306 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3307 mono_array_setref (out_args, 0, result);
3314 g_assert_not_reached ();
3316 } else if (!strcmp (m->name, "FieldSetter")) {
3317 MonoClass *k = this_arg->vtable->klass;
3323 /* If this is a proxy, then it must be a CBO */
3324 if (k == mono_defaults.transparent_proxy_class) {
3325 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3326 this_arg = tp->rp->unwrapped_server;
3327 g_assert (this_arg);
3328 k = this_arg->vtable->klass;
3331 name = mono_array_get (params, MonoString *, 1);
3332 str = mono_string_to_utf8_checked (name, &error);
3333 if (mono_error_set_pending_exception (&error))
3337 MonoClassField* field = mono_class_get_field_from_name (k, str);
3340 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3341 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3343 if (field_klass->valuetype) {
3344 size = mono_type_size (field->type, &align);
3345 g_assert (size == mono_class_value_size (field_klass, NULL));
3346 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3348 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3351 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3352 if (mono_error_set_pending_exception (&error))
3354 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3363 g_assert_not_reached ();
3368 for (i = 0; i < mono_array_length (params); i++) {
3369 if (sig->params [i]->byref)
3373 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3374 if (mono_error_set_pending_exception (&error))
3377 /* handle constructors only for objects already allocated */
3378 if (!strcmp (method->method->name, ".ctor"))
3379 g_assert (this_arg);
3381 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3382 g_assert (!method->method->klass->valuetype);
3383 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3384 if (mono_error_set_pending_exception (&error))
3387 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3388 if (sig->params [i]->byref) {
3390 arg = mono_array_get (params, gpointer, i);
3391 mono_array_setref (out_args, j, arg);
3396 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3403 read_enum_value (const char *mem, int type)
3406 case MONO_TYPE_BOOLEAN:
3408 return *(guint8*)mem;
3410 return *(gint8*)mem;
3411 case MONO_TYPE_CHAR:
3413 return read16 (mem);
3415 return (gint16) read16 (mem);
3417 return read32 (mem);
3419 return (gint32) read32 (mem);
3422 return read64 (mem);
3424 g_assert_not_reached ();
3430 write_enum_value (char *mem, int type, guint64 value)
3434 case MONO_TYPE_I1: {
3435 guint8 *p = (guint8*)mem;
3441 case MONO_TYPE_CHAR: {
3442 guint16 *p = (guint16 *)mem;
3447 case MONO_TYPE_I4: {
3448 guint32 *p = (guint32 *)mem;
3453 case MONO_TYPE_I8: {
3454 guint64 *p = (guint64 *)mem;
3459 g_assert_not_reached ();
3464 ICALL_EXPORT MonoObject *
3465 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3473 domain = mono_object_domain (enumType);
3474 enumc = mono_class_from_mono_type (enumType->type);
3476 mono_class_init_checked (enumc, &error);
3477 if (mono_error_set_pending_exception (&error))
3480 etype = mono_class_enum_basetype (enumc);
3482 res = mono_object_new_checked (domain, enumc, &error);
3483 if (mono_error_set_pending_exception (&error))
3485 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3490 ICALL_EXPORT MonoBoolean
3491 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3493 int size = mono_class_value_size (a->vtable->klass, NULL);
3494 guint64 a_val = 0, b_val = 0;
3496 memcpy (&a_val, mono_object_unbox (a), size);
3497 memcpy (&b_val, mono_object_unbox (b), size);
3499 return (a_val & b_val) == b_val;
3502 ICALL_EXPORT MonoObject *
3503 ves_icall_System_Enum_get_value (MonoObject *eobj)
3515 g_assert (eobj->vtable->klass->enumtype);
3517 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3518 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3519 if (mono_error_set_pending_exception (&error))
3521 dst = (char *)res + sizeof (MonoObject);
3522 src = (char *)eobj + sizeof (MonoObject);
3523 size = mono_class_value_size (enumc, NULL);
3525 memcpy (dst, src, size);
3530 ICALL_EXPORT MonoReflectionType *
3531 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3534 MonoReflectionType *ret;
3538 klass = mono_class_from_mono_type (type->type);
3539 mono_class_init_checked (klass, &error);
3540 if (mono_error_set_pending_exception (&error))
3543 etype = mono_class_enum_basetype (klass);
3545 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3549 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3550 mono_error_set_pending_exception (&error);
3556 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3558 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3559 gpointer odata = (char *)other + sizeof (MonoObject);
3560 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3561 g_assert (basetype);
3566 if (eobj->vtable->klass != other->vtable->klass)
3569 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3570 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3571 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3574 return me > other ? 1 : -1; \
3577 switch (basetype->type) {
3579 COMPARE_ENUM_VALUES (guint8);
3581 COMPARE_ENUM_VALUES (gint8);
3582 case MONO_TYPE_CHAR:
3584 COMPARE_ENUM_VALUES (guint16);
3586 COMPARE_ENUM_VALUES (gint16);
3588 COMPARE_ENUM_VALUES (guint32);
3590 COMPARE_ENUM_VALUES (gint32);
3592 COMPARE_ENUM_VALUES (guint64);
3594 COMPARE_ENUM_VALUES (gint64);
3598 #undef COMPARE_ENUM_VALUES
3599 /* indicates that the enum was of an unsupported unerlying type */
3604 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3606 gpointer data = (char *)eobj + sizeof (MonoObject);
3607 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3608 g_assert (basetype);
3610 switch (basetype->type) {
3611 case MONO_TYPE_I1: {
3612 gint8 value = *((gint8*)data);
3613 return ((int)value ^ (int)value << 8);
3616 return *((guint8*)data);
3617 case MONO_TYPE_CHAR:
3619 return *((guint16*)data);
3621 case MONO_TYPE_I2: {
3622 gint16 value = *((gint16*)data);
3623 return ((int)(guint16)value | (((int)value) << 16));
3626 return *((guint32*)data);
3628 return *((gint32*)data);
3630 case MONO_TYPE_I8: {
3631 gint64 value = *((gint64*)data);
3632 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3635 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3641 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3643 mono_error_init (error);
3644 HANDLE_FUNCTION_ENTER();
3645 guint64 field_value;
3647 MonoTypeEnum def_type;
3649 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3651 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3653 if (mono_field_is_deleted (field))
3655 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3658 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3660 p = mono_class_get_field_default_value (field, &def_type);
3661 /* len = */ mono_metadata_decode_blob_size (p, &p);
3663 field_value = read_enum_value (p, base_type);
3664 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3666 if (*previous_value > field_value)
3669 *previous_value = field_value;
3672 HANDLE_FUNCTION_RETURN();
3675 ICALL_EXPORT MonoBoolean
3676 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3678 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3679 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3680 guint j = 0, nvalues;
3682 MonoClassField *field;
3684 guint64 previous_value = 0;
3685 gboolean sorted = TRUE;
3687 mono_error_init (error);
3688 mono_class_init_checked (enumc, error);
3689 return_val_if_nok (error, FALSE);
3691 if (!enumc->enumtype) {
3692 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3696 base_type = mono_class_enum_basetype (enumc)->type;
3698 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3699 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3700 return_val_if_nok (error, FALSE);
3701 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3702 return_val_if_nok (error, FALSE);
3705 while ((field = mono_class_get_fields (enumc, &iter))) {
3706 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3710 return_val_if_nok (error, FALSE);
3716 BFLAGS_IgnoreCase = 1,
3717 BFLAGS_DeclaredOnly = 2,
3718 BFLAGS_Instance = 4,
3720 BFLAGS_Public = 0x10,
3721 BFLAGS_NonPublic = 0x20,
3722 BFLAGS_FlattenHierarchy = 0x40,
3723 BFLAGS_InvokeMethod = 0x100,
3724 BFLAGS_CreateInstance = 0x200,
3725 BFLAGS_GetField = 0x400,
3726 BFLAGS_SetField = 0x800,
3727 BFLAGS_GetProperty = 0x1000,
3728 BFLAGS_SetProperty = 0x2000,
3729 BFLAGS_ExactBinding = 0x10000,
3730 BFLAGS_SuppressChangeType = 0x20000,
3731 BFLAGS_OptionalParamBinding = 0x40000
3734 ICALL_EXPORT GPtrArray*
3735 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3738 MonoClass *startklass, *klass;
3741 int (*compare_func) (const char *s1, const char *s2) = NULL;
3742 MonoClassField *field;
3744 if (type->type->byref) {
3745 return g_ptr_array_new ();
3748 mono_error_init (&error);
3750 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3752 klass = startklass = mono_class_from_mono_type (type->type);
3754 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3757 if (mono_class_has_failure (klass)) {
3758 mono_error_set_for_class_failure (&error, klass);
3763 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3764 guint32 flags = mono_field_get_flags (field);
3766 if (mono_field_is_deleted_with_flags (field, flags))
3768 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3769 if (bflags & BFLAGS_Public)
3771 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3772 if (bflags & BFLAGS_NonPublic) {
3779 if (flags & FIELD_ATTRIBUTE_STATIC) {
3780 if (bflags & BFLAGS_Static)
3781 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3784 if (bflags & BFLAGS_Instance)
3791 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3794 g_ptr_array_add (ptr_array, field);
3796 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3802 g_ptr_array_free (ptr_array, TRUE);
3803 mono_error_set_pending_exception (&error);
3808 method_nonpublic (MonoMethod* method, gboolean start_klass)
3810 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3811 case METHOD_ATTRIBUTE_ASSEM:
3812 return (start_klass || mono_defaults.generic_ilist_class);
3813 case METHOD_ATTRIBUTE_PRIVATE:
3815 case METHOD_ATTRIBUTE_PUBLIC:
3823 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3826 MonoClass *startklass;
3830 /*FIXME, use MonoBitSet*/
3831 guint32 method_slots_default [8];
3832 guint32 *method_slots = NULL;
3833 int (*compare_func) (const char *s1, const char *s2) = NULL;
3835 array = g_ptr_array_new ();
3837 mono_error_init (error);
3840 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3842 /* An optimization for calls made from Delegate:CreateDelegate () */
3843 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3844 method = mono_get_delegate_invoke (klass);
3847 g_ptr_array_add (array, method);
3851 mono_class_setup_methods (klass);
3852 mono_class_setup_vtable (klass);
3853 if (mono_class_has_failure (klass))
3856 if (is_generic_parameter (&klass->byval_arg))
3857 nslots = mono_class_get_vtable_size (klass->parent);
3859 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3860 if (nslots >= sizeof (method_slots_default) * 8) {
3861 method_slots = g_new0 (guint32, nslots / 32 + 1);
3863 method_slots = method_slots_default;
3864 memset (method_slots, 0, sizeof (method_slots_default));
3867 mono_class_setup_methods (klass);
3868 mono_class_setup_vtable (klass);
3869 if (mono_class_has_failure (klass))
3873 while ((method = mono_class_get_methods (klass, &iter))) {
3875 if (method->slot != -1) {
3876 g_assert (method->slot < nslots);
3877 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3879 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3880 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3883 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3885 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3886 if (bflags & BFLAGS_Public)
3888 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3894 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3895 if (bflags & BFLAGS_Static)
3896 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3899 if (bflags & BFLAGS_Instance)
3907 if (compare_func (name, method->name))
3912 g_ptr_array_add (array, method);
3914 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3916 if (method_slots != method_slots_default)
3917 g_free (method_slots);
3922 if (method_slots != method_slots_default)
3923 g_free (method_slots);
3924 g_ptr_array_free (array, TRUE);
3926 g_assert (mono_class_has_failure (klass));
3927 mono_error_set_for_class_failure (error, klass);
3931 ICALL_EXPORT GPtrArray*
3932 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3935 GPtrArray *method_array;
3938 klass = mono_class_from_mono_type (type->type);
3939 if (type->type->byref) {
3940 return g_ptr_array_new ();
3943 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3944 mono_error_set_pending_exception (&error);
3945 return method_array;
3948 ICALL_EXPORT GPtrArray*
3949 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3951 MonoClass *startklass, *klass;
3954 gpointer iter = NULL;
3955 GPtrArray *res_array;
3958 if (type->type->byref) {
3959 return g_ptr_array_new ();
3962 klass = startklass = mono_class_from_mono_type (type->type);
3964 mono_class_setup_methods (klass);
3965 if (mono_class_has_failure (klass)) {
3966 mono_error_init (&error);
3967 mono_error_set_for_class_failure (&error, klass);
3968 mono_error_set_pending_exception (&error);
3972 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3975 while ((method = mono_class_get_methods (klass, &iter))) {
3977 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3979 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3980 if (bflags & BFLAGS_Public)
3983 if (bflags & BFLAGS_NonPublic)
3989 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3990 if (bflags & BFLAGS_Static)
3991 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3994 if (bflags & BFLAGS_Instance)
4000 g_ptr_array_add (res_array, method);
4007 property_hash (gconstpointer data)
4009 MonoProperty *prop = (MonoProperty*)data;
4011 return g_str_hash (prop->name);
4015 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4017 if (method1->slot != -1 && method1->slot == method2->slot)
4020 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4021 if (method1->is_inflated)
4022 method1 = ((MonoMethodInflated*) method1)->declaring;
4023 if (method2->is_inflated)
4024 method2 = ((MonoMethodInflated*) method2)->declaring;
4027 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4031 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4033 // Properties are hide-by-name-and-signature
4034 if (!g_str_equal (prop1->name, prop2->name))
4037 /* If we see a property in a generic method, we want to
4038 compare the generic signatures, not the inflated signatures
4039 because we might conflate two properties that were
4043 public T this[T t] { getter { return t; } } // method 1
4044 public U this[U u] { getter { return u; } } // method 2
4047 If we see int Foo<int,int>::Item[int] we need to know if
4048 the indexer came from method 1 or from method 2, and we
4049 shouldn't conflate them. (Bugzilla 36283)
4051 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4054 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4061 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4066 return method_nonpublic (accessor, start_klass);
4069 ICALL_EXPORT GPtrArray*
4070 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4073 MonoClass *startklass, *klass;
4078 int (*compare_func) (const char *s1, const char *s2) = NULL;
4080 GHashTable *properties = NULL;
4081 GPtrArray *res_array;
4083 if (type->type->byref) {
4084 return g_ptr_array_new ();
4087 mono_error_init (&error);
4089 klass = startklass = mono_class_from_mono_type (type->type);
4091 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4093 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4095 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4097 mono_class_setup_methods (klass);
4098 mono_class_setup_vtable (klass);
4099 if (mono_class_has_failure (klass)) {
4100 mono_error_set_for_class_failure (&error, klass);
4105 while ((prop = mono_class_get_properties (klass, &iter))) {
4111 flags = method->flags;
4114 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4115 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4116 if (bflags & BFLAGS_Public)
4118 } else if (bflags & BFLAGS_NonPublic) {
4119 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4120 property_accessor_nonpublic(prop->set, startklass == klass)) {
4127 if (flags & METHOD_ATTRIBUTE_STATIC) {
4128 if (bflags & BFLAGS_Static)
4129 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4132 if (bflags & BFLAGS_Instance)
4140 if (propname != NULL && compare_func (propname, prop->name))
4143 if (g_hash_table_lookup (properties, prop))
4146 g_ptr_array_add (res_array, prop);
4148 g_hash_table_insert (properties, prop, prop);
4150 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4153 g_hash_table_destroy (properties);
4160 g_hash_table_destroy (properties);
4161 g_ptr_array_free (res_array, TRUE);
4163 mono_error_set_pending_exception (&error);
4169 event_hash (gconstpointer data)
4171 MonoEvent *event = (MonoEvent*)data;
4173 return g_str_hash (event->name);
4177 event_equal (MonoEvent *event1, MonoEvent *event2)
4179 // Events are hide-by-name
4180 return g_str_equal (event1->name, event2->name);
4183 ICALL_EXPORT GPtrArray*
4184 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4187 MonoClass *startklass, *klass;
4192 int (*compare_func) (const char *s1, const char *s2) = NULL;
4193 GHashTable *events = NULL;
4194 GPtrArray *res_array;
4196 if (type->type->byref) {
4197 return g_ptr_array_new ();
4200 mono_error_init (&error);
4202 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4204 res_array = g_ptr_array_sized_new (4);
4206 klass = startklass = mono_class_from_mono_type (type->type);
4208 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4210 mono_class_setup_methods (klass);
4211 mono_class_setup_vtable (klass);
4212 if (mono_class_has_failure (klass)) {
4213 mono_error_set_for_class_failure (&error, klass);
4218 while ((event = mono_class_get_events (klass, &iter))) {
4220 method = event->add;
4222 method = event->remove;
4224 method = event->raise;
4226 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4227 if (bflags & BFLAGS_Public)
4229 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4230 if (bflags & BFLAGS_NonPublic)
4235 if (bflags & BFLAGS_NonPublic)
4241 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4242 if (bflags & BFLAGS_Static)
4243 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4246 if (bflags & BFLAGS_Instance)
4251 if (bflags & BFLAGS_Instance)
4256 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4259 if (g_hash_table_lookup (events, event))
4262 g_ptr_array_add (res_array, event);
4264 g_hash_table_insert (events, event, event);
4266 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4269 g_hash_table_destroy (events);
4275 g_hash_table_destroy (events);
4277 g_ptr_array_free (res_array, TRUE);
4279 mono_error_set_pending_exception (&error);
4283 ICALL_EXPORT GPtrArray *
4284 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4290 GPtrArray *res_array;
4292 if (type->type->byref) {
4293 return g_ptr_array_new ();
4296 klass = mono_class_from_mono_type (type->type);
4299 * If a nested type is generic, return its generic type definition.
4300 * Note that this means that the return value is essentially the set
4301 * of nested types of the generic type definition of @klass.
4303 * A note in MSDN claims that a generic type definition can have
4304 * nested types that aren't generic. In any case, the container of that
4305 * nested type would be the generic type definition.
4307 if (mono_class_is_ginst (klass))
4308 klass = mono_class_get_generic_class (klass)->container_class;
4310 res_array = g_ptr_array_new ();
4313 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4315 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4316 if (bflags & BFLAGS_Public)
4319 if (bflags & BFLAGS_NonPublic)
4325 if (str != NULL && strcmp (nested->name, str))
4328 g_ptr_array_add (res_array, &nested->byval_arg);
4334 ICALL_EXPORT MonoReflectionType*
4335 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4338 MonoReflectionType *ret;
4340 MonoType *type = NULL;
4341 MonoTypeNameParse info;
4342 gboolean type_resolve;
4344 /* On MS.NET, this does not fire a TypeResolve event */
4345 type_resolve = TRUE;
4346 str = mono_string_to_utf8_checked (name, &error);
4347 if (mono_error_set_pending_exception (&error))
4349 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4350 if (!mono_reflection_parse_type (str, &info)) {
4352 mono_reflection_free_type_info (&info);
4354 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4357 /*g_print ("failed parse\n");*/
4361 if (info.assembly.name) {
4363 mono_reflection_free_type_info (&info);
4365 /* 1.0 and 2.0 throw different exceptions */
4366 if (mono_defaults.generic_ilist_class)
4367 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4369 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4375 if (module != NULL) {
4376 if (module->image) {
4377 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4378 if (!is_ok (&error)) {
4380 mono_reflection_free_type_info (&info);
4381 mono_error_set_pending_exception (&error);
4388 if (assembly_is_dynamic (assembly->assembly)) {
4389 /* Enumerate all modules */
4390 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4394 if (abuilder->modules) {
4395 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4396 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4397 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4398 if (!is_ok (&error)) {
4400 mono_reflection_free_type_info (&info);
4401 mono_error_set_pending_exception (&error);
4409 if (!type && abuilder->loaded_modules) {
4410 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4411 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4412 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4413 if (!is_ok (&error)) {
4415 mono_reflection_free_type_info (&info);
4416 mono_error_set_pending_exception (&error);
4425 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4426 if (!is_ok (&error)) {
4428 mono_reflection_free_type_info (&info);
4429 mono_error_set_pending_exception (&error);
4434 mono_reflection_free_type_info (&info);
4436 MonoException *e = NULL;
4439 e = mono_get_exception_type_load (name, NULL);
4442 mono_set_pending_exception (e);
4446 if (type->type == MONO_TYPE_CLASS) {
4447 MonoClass *klass = mono_type_get_class (type);
4449 /* need to report exceptions ? */
4450 if (throwOnError && mono_class_has_failure (klass)) {
4451 /* report SecurityException (or others) that occured when loading the assembly */
4452 mono_error_set_for_class_failure (&error, klass);
4453 mono_error_set_pending_exception (&error);
4458 /* g_print ("got it\n"); */
4459 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4460 mono_error_set_pending_exception (&error);
4466 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4469 gchar *shadow_ini_file;
4472 /* Check for shadow-copied assembly */
4473 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4474 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4476 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4477 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4483 g_free (shadow_ini_file);
4484 if (content != NULL) {
4487 *filename = content;
4494 ICALL_EXPORT MonoString *
4495 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4497 MonoDomain *domain = mono_object_domain (assembly);
4498 MonoAssembly *mass = assembly->assembly;
4499 MonoString *res = NULL;
4504 if (g_path_is_absolute (mass->image->name)) {
4505 absolute = g_strdup (mass->image->name);
4506 dirname = g_path_get_dirname (absolute);
4508 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4509 dirname = g_strdup (mass->basedir);
4512 replace_shadow_path (domain, dirname, &absolute);
4515 mono_icall_make_platform_path (absolute);
4518 uri = g_filename_to_uri (absolute, NULL, NULL);
4520 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4521 uri = g_strconcat (prepend, absolute, NULL);
4525 res = mono_string_new (domain, uri);
4532 ICALL_EXPORT MonoBoolean
4533 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4535 MonoAssembly *mass = assembly->assembly;
4537 return mass->in_gac;
4540 ICALL_EXPORT MonoReflectionAssembly*
4541 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4546 MonoImageOpenStatus status;
4547 MonoReflectionAssembly* result = NULL;
4549 name = mono_string_to_utf8_checked (mname, &error);
4550 if (mono_error_set_pending_exception (&error))
4552 res = mono_assembly_load_with_partial_name (name, &status);
4558 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4560 mono_error_set_pending_exception (&error);
4564 ICALL_EXPORT MonoStringHandle
4565 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4567 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4568 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4569 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4572 ICALL_EXPORT MonoBoolean
4573 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4575 return assembly->assembly->ref_only;
4578 ICALL_EXPORT MonoStringHandle
4579 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4581 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4582 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4584 return mono_string_new_handle (domain, assembly->image->version, error);
4587 ICALL_EXPORT MonoReflectionMethod*
4588 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4591 MonoReflectionMethod *res = NULL;
4594 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4598 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4599 if (!mono_error_ok (&error))
4602 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4605 if (!mono_error_ok (&error))
4606 mono_error_set_pending_exception (&error);
4610 ICALL_EXPORT MonoReflectionModuleHandle
4611 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4613 mono_error_init (error);
4614 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4615 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4616 return mono_module_get_object_handle (domain, a->image, error);
4619 ICALL_EXPORT MonoArray*
4620 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4623 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4624 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4625 if (mono_error_set_pending_exception (&error))
4630 for (i = 0; i < table->rows; ++i) {
4631 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4632 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4637 ICALL_EXPORT MonoStringHandle
4638 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4641 guint8 aotid_sum = 0;
4642 MonoDomain* domain = mono_domain_get ();
4644 if (!domain->entry_assembly || !domain->entry_assembly->image)
4647 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4649 for (i = 0; i < 16; ++i)
4650 aotid_sum |= (*aotid)[i];
4655 gchar *guid = mono_guid_to_string((guint8*) aotid);
4656 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4661 static MonoAssemblyName*
4662 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4664 mono_error_init (error);
4665 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4667 mono_assembly_get_assemblyref (image, i, aname);
4668 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4669 /* name and culture are pointers into the image tables, but we need
4670 * real malloc'd strings (so that we can g_free() them later from
4671 * Mono.RuntimeMarshal.FreeAssemblyName) */
4672 aname->name = g_strdup (aname->name);
4673 aname->culture = g_strdup (aname->culture);
4674 /* Don't need the hash value in managed */
4675 aname->hash_value = NULL;
4676 aname->hash_len = 0;
4677 g_assert (aname->public_key == NULL);
4679 /* note: this function doesn't return the codebase on purpose (i.e. it can
4680 be used under partial trust as path information isn't present). */
4684 ICALL_EXPORT GPtrArray*
4685 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4687 mono_error_init (error);
4688 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4689 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4690 MonoImage *image = ass->image;
4692 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4693 int count = t->rows;
4695 GPtrArray *result = g_ptr_array_sized_new (count);
4697 for (int i = 0; i < count; i++) {
4698 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4701 g_ptr_array_add (result, aname);
4706 /* move this in some file in mono/util/ */
4708 g_concat_dir_and_file (const char *dir, const char *file)
4710 g_return_val_if_fail (dir != NULL, NULL);
4711 g_return_val_if_fail (file != NULL, NULL);
4714 * If the directory name doesn't have a / on the end, we need
4715 * to add one so we get a proper path to the file
4717 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4718 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4720 return g_strconcat (dir, file, NULL);
4724 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4726 mono_error_init (error);
4727 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4728 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4729 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4731 guint32 cols [MONO_MANIFEST_SIZE];
4732 guint32 impl, file_idx;
4736 char *n = mono_string_handle_to_utf8 (name, error);
4737 return_val_if_nok (error, NULL);
4739 for (i = 0; i < table->rows; ++i) {
4740 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4741 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4742 if (strcmp (val, n) == 0)
4746 if (i == table->rows)
4749 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4752 * this code should only be called after obtaining the
4753 * ResourceInfo and handling the other cases.
4755 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4756 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4758 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4759 if (!is_ok (error) || !module)
4763 module = assembly->image;
4766 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4769 MONO_HANDLE_ASSIGN (ref_module, rm);
4771 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4775 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4777 HANDLE_FUNCTION_ENTER ();
4778 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4779 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4780 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4782 guint32 cols [MONO_MANIFEST_SIZE];
4783 guint32 file_cols [MONO_FILE_SIZE];
4787 gboolean result = FALSE;
4789 n = mono_string_handle_to_utf8 (name, error);
4793 for (i = 0; i < table->rows; ++i) {
4794 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4795 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4796 if (strcmp (val, n) == 0)
4800 if (i == table->rows)
4803 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4804 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4807 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4808 case MONO_IMPLEMENTATION_FILE:
4809 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4810 table = &assembly->image->tables [MONO_TABLE_FILE];
4811 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4812 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4813 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4814 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4815 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4817 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4820 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4821 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4822 mono_assembly_load_reference (assembly->image, i - 1);
4823 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4824 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4827 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4830 MONO_HANDLE_SET (info, assembly, assm_obj);
4832 /* Obtain info recursively */
4833 get_manifest_resource_info_internal (assm_obj, name, info, error);
4836 guint32 location = MONO_HANDLE_GETVAL (info, location);
4837 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4838 MONO_HANDLE_SETVAL (info, location, guint32, location);
4841 case MONO_IMPLEMENTATION_EXP_TYPE:
4842 g_assert_not_reached ();
4849 HANDLE_FUNCTION_RETURN_VAL (result);
4852 ICALL_EXPORT gboolean
4853 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4855 mono_error_init (error);
4856 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4859 ICALL_EXPORT MonoObject*
4860 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4863 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4864 MonoArray *result = NULL;
4869 /* check hash if needed */
4871 n = mono_string_to_utf8_checked (name, &error);
4872 if (mono_error_set_pending_exception (&error))
4875 for (i = 0; i < table->rows; ++i) {
4876 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4877 if (strcmp (val, n) == 0) {
4880 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4881 fn = mono_string_new (mono_object_domain (assembly), n);
4883 return (MonoObject*)fn;
4891 for (i = 0; i < table->rows; ++i) {
4892 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4896 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4897 if (mono_error_set_pending_exception (&error))
4902 for (i = 0; i < table->rows; ++i) {
4903 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4904 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4905 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4906 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4911 return (MonoObject*)result;
4915 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4917 HANDLE_FUNCTION_ENTER ();
4918 mono_error_init (error);
4920 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4924 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4929 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4933 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4935 HANDLE_FUNCTION_ENTER ();
4936 mono_error_init (error);
4938 guint32 cols [MONO_FILE_SIZE];
4939 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4940 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4941 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4944 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4946 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4950 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4951 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4954 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
4957 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4961 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4964 ICALL_EXPORT MonoArrayHandle
4965 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4967 mono_error_init (error);
4968 MonoDomain *domain = mono_domain_get();
4969 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4971 int i, j, file_count = 0;
4972 MonoImage **modules;
4973 guint32 module_count, real_module_count;
4974 MonoTableInfo *table;
4975 MonoImage *image = assembly->image;
4977 g_assert (image != NULL);
4978 g_assert (!assembly_is_dynamic (assembly));
4980 table = &image->tables [MONO_TABLE_FILE];
4981 file_count = table->rows;
4983 modules = image->modules;
4984 module_count = image->module_count;
4986 real_module_count = 0;
4987 for (i = 0; i < module_count; ++i)
4989 real_module_count ++;
4991 klass = mono_class_get_module_class ();
4992 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
4996 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5000 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5003 for (i = 0; i < module_count; ++i)
5004 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5007 for (i = 0; i < file_count; ++i, ++j) {
5008 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5014 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5017 ICALL_EXPORT MonoReflectionMethod*
5018 ves_icall_GetCurrentMethod (void)
5020 MonoReflectionMethod *res = NULL;
5023 MonoMethod *m = mono_method_get_last_managed ();
5026 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5030 while (m->is_inflated)
5031 m = ((MonoMethodInflated*)m)->declaring;
5033 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5034 mono_error_set_pending_exception (&error);
5040 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5043 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5046 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5047 //method is inflated, we should inflate it on the other class
5048 MonoGenericContext ctx;
5049 ctx.method_inst = inflated->context.method_inst;
5050 ctx.class_inst = inflated->context.class_inst;
5051 if (mono_class_is_ginst (klass))
5052 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5053 else if (mono_class_is_gtd (klass))
5054 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5055 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5056 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5060 mono_class_setup_methods (method->klass);
5061 if (mono_class_has_failure (method->klass))
5063 int mcount = mono_class_get_method_count (method->klass);
5064 for (i = 0; i < mcount; ++i) {
5065 if (method->klass->methods [i] == method) {
5070 mono_class_setup_methods (klass);
5071 if (mono_class_has_failure (klass))
5073 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5074 return klass->methods [offset];
5077 ICALL_EXPORT MonoReflectionMethod*
5078 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5080 MonoReflectionMethod *res = NULL;
5083 if (type && generic_check) {
5084 klass = mono_class_from_mono_type (type);
5085 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5088 if (method->klass != klass) {
5089 method = mono_method_get_equivalent_method (method, klass);
5094 klass = mono_class_from_mono_type (type);
5096 klass = method->klass;
5097 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5098 mono_error_set_pending_exception (&error);
5102 ICALL_EXPORT MonoReflectionMethodBody*
5103 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5106 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5107 mono_error_set_pending_exception (&error);
5111 ICALL_EXPORT MonoReflectionAssembly*
5112 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5115 MonoReflectionAssembly *result;
5116 MonoMethod *dest = NULL;
5118 mono_stack_walk_no_il (get_executing, &dest);
5120 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5122 mono_error_set_pending_exception (&error);
5127 ICALL_EXPORT MonoReflectionAssembly*
5128 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5131 MonoReflectionAssembly *result;
5132 MonoDomain* domain = mono_domain_get ();
5134 if (!domain->entry_assembly)
5137 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5139 mono_error_set_pending_exception (&error);
5143 ICALL_EXPORT MonoReflectionAssembly*
5144 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5149 MonoReflectionAssembly *result;
5152 mono_stack_walk_no_il (get_executing, &dest);
5154 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5158 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5161 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5163 mono_error_set_pending_exception (&error);
5167 ICALL_EXPORT MonoStringHandle
5168 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5169 gboolean assembly_qualified, MonoError *error)
5171 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5172 MonoType *type = MONO_HANDLE_RAW (object)->type;
5173 MonoTypeNameFormat format;
5174 MonoStringHandle res;
5178 format = assembly_qualified ?
5179 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5180 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5182 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5184 name = mono_type_get_name_full (type, format);
5186 return NULL_HANDLE_STRING;
5188 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5190 return NULL_HANDLE_STRING;
5193 res = mono_string_new_handle (domain, name, error);
5200 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5203 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5205 mono_class_init_checked (klass, &error);
5206 mono_error_set_pending_exception (&error);
5207 return mono_security_core_clr_class_level (klass);
5211 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5213 MonoClassField *field = rfield->field;
5214 return mono_security_core_clr_field_level (field, TRUE);
5218 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5220 MonoMethod *method = rfield->method;
5221 return mono_security_core_clr_method_level (method, TRUE);
5224 ICALL_EXPORT MonoString *
5225 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5227 MonoDomain *domain = mono_object_domain (assembly);
5228 MonoAssembly *mass = assembly->assembly;
5232 name = mono_stringify_assembly_name (&mass->aname);
5233 res = mono_string_new (domain, name);
5239 ICALL_EXPORT MonoAssemblyName *
5240 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5242 return &mass->aname;
5246 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5249 MonoImageOpenStatus status = MONO_IMAGE_OK;
5250 char *codebase = NULL;
5255 mono_error_init (error);
5257 filename = mono_string_handle_to_utf8 (fname, error);
5258 return_if_nok (error);
5260 dirname = g_path_get_dirname (filename);
5261 replace_shadow_path (mono_domain_get (), dirname, &filename);
5264 image = mono_image_open (filename, &status);
5267 if (status == MONO_IMAGE_IMAGE_INVALID)
5268 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5270 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5275 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5277 mono_image_close (image);
5279 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5283 if (filename != NULL && *filename != '\0') {
5286 codebase = g_strdup (filename);
5288 mono_icall_make_platform_path (codebase);
5290 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5292 result = g_strconcat (prepend, codebase, NULL);
5296 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5299 mono_image_close (image);
5303 ICALL_EXPORT MonoBoolean
5304 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5305 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5307 MonoBoolean result = FALSE;
5308 MonoDeclSecurityEntry entry;
5310 /* SecurityAction.RequestMinimum */
5311 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5312 *minimum = entry.blob;
5313 *minLength = entry.size;
5316 /* SecurityAction.RequestOptional */
5317 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5318 *optional = entry.blob;
5319 *optLength = entry.size;
5322 /* SecurityAction.RequestRefuse */
5323 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5324 *refused = entry.blob;
5325 *refLength = entry.size;
5333 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5335 guint32 attrs, visibility;
5337 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5338 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5339 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5342 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5348 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5350 mono_error_init (error);
5351 HANDLE_FUNCTION_ENTER ();
5352 MonoError klass_error;
5353 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5356 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5357 return_if_nok (error);
5359 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5361 MonoException *ex = mono_error_convert_to_exception (error);
5362 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5364 HANDLE_FUNCTION_RETURN ();
5367 static MonoArrayHandle
5368 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5370 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5373 mono_error_init (error);
5375 /* we start the count from 1 because we skip the special type <Module> */
5378 for (i = 1; i < tdef->rows; ++i) {
5379 if (mono_module_type_is_visible (tdef, image, i + 1))
5383 count = tdef->rows - 1;
5385 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5386 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5387 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5388 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5390 for (i = 1; i < tdef->rows; ++i) {
5391 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5392 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5393 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5402 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5404 HANDLE_FUNCTION_ENTER ();
5405 mono_error_init (error);
5406 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5407 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5411 /* Append the new types to the end of the array */
5412 if (mono_array_handle_length (res2) > 0) {
5415 len1 = mono_array_handle_length (res);
5416 len2 = mono_array_handle_length (res2);
5418 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5422 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5423 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5424 MONO_HANDLE_ASSIGN (res, res3);
5426 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5430 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5431 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5432 MONO_HANDLE_ASSIGN (exceptions, ex3);
5435 HANDLE_FUNCTION_RETURN ();
5439 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5441 HANDLE_FUNCTION_ENTER ();
5442 MonoError unboxed_error;
5443 mono_error_init (&unboxed_error);
5444 mono_error_set_for_class_failure (&unboxed_error, klass);
5446 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5447 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5448 HANDLE_FUNCTION_RETURN ();
5451 ICALL_EXPORT MonoArrayHandle
5452 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5454 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5457 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5458 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5460 g_assert (!assembly_is_dynamic (assembly));
5461 MonoImage *image = assembly->image;
5462 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5463 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5464 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5466 /* Append data from all modules in the assembly */
5467 for (i = 0; i < table->rows; ++i) {
5468 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5469 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5470 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5473 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5474 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5479 /* the ReflectionTypeLoadException must have all the types (Types property),
5480 * NULL replacing types which throws an exception. The LoaderException must
5481 * contain all exceptions for NULL items.
5484 int len = mono_array_handle_length (res);
5488 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5489 for (i = 0; i < len; i++) {
5490 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5492 if (!MONO_HANDLE_IS_NULL (t)) {
5493 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5494 if ((klass != NULL) && mono_class_has_failure (klass)) {
5495 /* keep the class in the list */
5496 list = g_list_append (list, klass);
5497 /* and replace Type with NULL */
5498 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5505 if (list || ex_count) {
5507 int j, length = g_list_length (list) + ex_count;
5509 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5510 if (!is_ok (error)) {
5512 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5514 /* Types for which mono_class_get_checked () succeeded */
5515 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5516 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5517 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5519 /* Types for which it don't */
5520 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5521 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5522 if (!MONO_HANDLE_IS_NULL (exc)) {
5523 g_assert (i < length);
5524 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5531 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5532 if (!is_ok (error)) {
5533 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5535 mono_error_set_exception_handle (error, exc);
5536 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5543 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5545 mono_assembly_name_free (aname);
5550 ICALL_EXPORT gboolean
5551 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5553 *is_version_definited = *is_token_defined = FALSE;
5555 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5558 ICALL_EXPORT MonoReflectionTypeHandle
5559 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5561 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5562 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5567 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5569 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5570 /* These images do not have a global type */
5573 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5577 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5583 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5585 /*if (module->image)
5586 mono_image_close (module->image);*/
5589 ICALL_EXPORT MonoStringHandle
5590 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5592 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5593 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5596 return mono_string_new_handle (domain, image->guid, error);
5600 static inline gpointer
5601 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5603 return (gpointer) (-1);
5605 #endif /* HOST_WIN32 */
5607 ICALL_EXPORT gpointer
5608 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5610 return mono_icall_module_get_hinstance (module);
5614 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5616 if (image_is_dynamic (image)) {
5617 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5618 *pe_kind = dyn->pe_kind;
5619 *machine = dyn->machine;
5622 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5623 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5628 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5630 return (image->md_version_major << 16) | (image->md_version_minor);
5633 ICALL_EXPORT MonoArrayHandle
5634 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5636 mono_error_init (error);
5638 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5639 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5642 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5645 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5646 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5647 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5649 int n = mono_array_handle_length (exceptions);
5650 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5651 for (int i = 0; i < n; ++i) {
5652 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5653 if (!MONO_HANDLE_IS_NULL (ex)) {
5654 mono_error_set_exception_handle (error, ex);
5655 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5663 mono_memberref_is_method (MonoImage *image, guint32 token)
5665 if (!image_is_dynamic (image)) {
5666 guint32 cols [MONO_MEMBERREF_SIZE];
5668 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5669 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5670 mono_metadata_decode_blob_size (sig, &sig);
5671 return (*sig != 0x6);
5674 MonoClass *handle_class;
5676 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5677 mono_error_cleanup (&error); /* just probing, ignore error */
5681 return mono_defaults.methodhandle_class == handle_class;
5686 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5689 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5690 mono_array_addr (type_args, MonoType*, 0));
5692 context->class_inst = NULL;
5694 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5695 mono_array_addr (method_args, MonoType*, 0));
5697 context->method_inst = NULL;
5700 ICALL_EXPORT MonoType*
5701 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5704 int table = mono_metadata_token_table (token);
5705 int index = mono_metadata_token_index (token);
5706 MonoGenericContext context;
5709 *resolve_error = ResolveTokenError_Other;
5711 /* Validate token */
5712 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5713 (table != MONO_TABLE_TYPESPEC)) {
5714 *resolve_error = ResolveTokenError_BadTable;
5718 if (image_is_dynamic (image)) {
5719 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5720 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5721 mono_error_cleanup (&error);
5722 return klass ? &klass->byval_arg : NULL;
5725 init_generic_context_from_args (&context, type_args, method_args);
5726 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5727 mono_error_cleanup (&error);
5728 return klass ? &klass->byval_arg : NULL;
5731 if ((index <= 0) || (index > image->tables [table].rows)) {
5732 *resolve_error = ResolveTokenError_OutOfRange;
5736 init_generic_context_from_args (&context, type_args, method_args);
5737 klass = mono_class_get_checked (image, token, &error);
5739 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5740 if (!mono_error_ok (&error)) {
5741 mono_error_set_pending_exception (&error);
5746 return &klass->byval_arg;
5751 ICALL_EXPORT MonoMethod*
5752 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5755 int table = mono_metadata_token_table (token);
5756 int index = mono_metadata_token_index (token);
5757 MonoGenericContext context;
5760 *resolve_error = ResolveTokenError_Other;
5762 /* Validate token */
5763 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5764 (table != MONO_TABLE_MEMBERREF)) {
5765 *resolve_error = ResolveTokenError_BadTable;
5769 if (image_is_dynamic (image)) {
5770 if (table == MONO_TABLE_METHOD) {
5771 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5772 mono_error_cleanup (&error);
5776 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5777 *resolve_error = ResolveTokenError_BadTable;
5781 init_generic_context_from_args (&context, type_args, method_args);
5782 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5783 mono_error_cleanup (&error);
5787 if ((index <= 0) || (index > image->tables [table].rows)) {
5788 *resolve_error = ResolveTokenError_OutOfRange;
5791 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5792 *resolve_error = ResolveTokenError_BadTable;
5796 init_generic_context_from_args (&context, type_args, method_args);
5797 method = mono_get_method_checked (image, token, NULL, &context, &error);
5798 mono_error_set_pending_exception (&error);
5803 ICALL_EXPORT MonoString*
5804 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5807 int index = mono_metadata_token_index (token);
5809 *resolve_error = ResolveTokenError_Other;
5811 /* Validate token */
5812 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5813 *resolve_error = ResolveTokenError_BadTable;
5817 if (image_is_dynamic (image)) {
5818 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5819 mono_error_cleanup (&error);
5823 if ((index <= 0) || (index >= image->heap_us.size)) {
5824 *resolve_error = ResolveTokenError_OutOfRange;
5828 /* FIXME: What to do if the index points into the middle of a string ? */
5830 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5831 mono_error_set_pending_exception (&error);
5835 ICALL_EXPORT MonoClassField*
5836 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5840 int table = mono_metadata_token_table (token);
5841 int index = mono_metadata_token_index (token);
5842 MonoGenericContext context;
5843 MonoClassField *field;
5845 *resolve_error = ResolveTokenError_Other;
5847 /* Validate token */
5848 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5849 *resolve_error = ResolveTokenError_BadTable;
5853 if (image_is_dynamic (image)) {
5854 if (table == MONO_TABLE_FIELD) {
5855 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5856 mono_error_cleanup (&error);
5860 if (mono_memberref_is_method (image, token)) {
5861 *resolve_error = ResolveTokenError_BadTable;
5865 init_generic_context_from_args (&context, type_args, method_args);
5866 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5867 mono_error_cleanup (&error);
5871 if ((index <= 0) || (index > image->tables [table].rows)) {
5872 *resolve_error = ResolveTokenError_OutOfRange;
5875 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5876 *resolve_error = ResolveTokenError_BadTable;
5880 init_generic_context_from_args (&context, type_args, method_args);
5881 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5882 mono_error_set_pending_exception (&error);
5888 ICALL_EXPORT MonoObject*
5889 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5893 int table = mono_metadata_token_table (token);
5895 *error = ResolveTokenError_Other;
5898 case MONO_TABLE_TYPEDEF:
5899 case MONO_TABLE_TYPEREF:
5900 case MONO_TABLE_TYPESPEC: {
5901 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5903 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5904 mono_error_set_pending_exception (&merror);
5911 case MONO_TABLE_METHOD:
5912 case MONO_TABLE_METHODSPEC: {
5913 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5915 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5916 mono_error_set_pending_exception (&merror);
5922 case MONO_TABLE_FIELD: {
5923 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5925 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5926 mono_error_set_pending_exception (&merror);
5932 case MONO_TABLE_MEMBERREF:
5933 if (mono_memberref_is_method (image, token)) {
5934 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5936 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5937 mono_error_set_pending_exception (&merror);
5944 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5946 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5947 mono_error_set_pending_exception (&merror);
5956 *error = ResolveTokenError_BadTable;
5962 ICALL_EXPORT MonoArray*
5963 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5966 int table = mono_metadata_token_table (token);
5967 int idx = mono_metadata_token_index (token);
5968 MonoTableInfo *tables = image->tables;
5973 *resolve_error = ResolveTokenError_OutOfRange;
5975 /* FIXME: Support other tables ? */
5976 if (table != MONO_TABLE_STANDALONESIG)
5979 if (image_is_dynamic (image))
5982 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5985 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5987 ptr = mono_metadata_blob_heap (image, sig);
5988 len = mono_metadata_decode_blob_size (ptr, &ptr);
5990 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
5991 if (mono_error_set_pending_exception (&error))
5993 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5997 ICALL_EXPORT MonoBoolean
5998 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6004 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6010 check_for_invalid_type (MonoClass *klass, MonoError *error)
6014 mono_error_init (error);
6016 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6019 name = mono_type_get_full_name (klass);
6020 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6022 ICALL_EXPORT MonoReflectionType *
6023 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6026 MonoReflectionType *ret;
6027 MonoClass *klass, *aklass;
6029 klass = mono_class_from_mono_type (type->type);
6030 check_for_invalid_type (klass, &error);
6031 if (mono_error_set_pending_exception (&error))
6034 if (rank == 0) //single dimentional array
6035 aklass = mono_array_class_get (klass, 1);
6037 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6039 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6040 mono_error_set_pending_exception (&error);
6045 ICALL_EXPORT MonoReflectionType *
6046 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6049 MonoReflectionType *ret;
6052 klass = mono_class_from_mono_type (type->type);
6053 mono_class_init_checked (klass, &error);
6054 if (mono_error_set_pending_exception (&error))
6057 check_for_invalid_type (klass, &error);
6058 if (mono_error_set_pending_exception (&error))
6061 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6062 mono_error_set_pending_exception (&error);
6067 ICALL_EXPORT MonoReflectionType *
6068 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6071 MonoReflectionType *ret;
6072 MonoClass *klass, *pklass;
6074 klass = mono_class_from_mono_type (type->type);
6075 mono_class_init_checked (klass, &error);
6076 if (mono_error_set_pending_exception (&error))
6078 check_for_invalid_type (klass, &error);
6079 if (mono_error_set_pending_exception (&error))
6082 pklass = mono_ptr_class_get (type->type);
6084 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6085 mono_error_set_pending_exception (&error);
6090 ICALL_EXPORT MonoObject *
6091 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6092 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6095 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6096 MonoObject *delegate;
6098 MonoMethod *method = info->method;
6099 MonoMethodSignature *sig = mono_method_signature(method);
6101 mono_class_init_checked (delegate_class, &error);
6102 if (mono_error_set_pending_exception (&error))
6105 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6106 /* FIXME improve this exception message */
6107 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6109 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6110 mono_error_set_pending_exception (&error);
6114 if (mono_security_core_clr_enabled ()) {
6115 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6116 if (throwOnBindFailure)
6117 mono_error_set_pending_exception (&error);
6119 mono_error_cleanup (&error);
6124 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6125 if (!method->is_inflated) {
6126 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"));
6131 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6132 if (mono_error_set_pending_exception (&error))
6135 if (method_is_dynamic (method)) {
6136 /* Creating a trampoline would leak memory */
6137 func = mono_compile_method_checked (method, &error);
6138 if (mono_error_set_pending_exception (&error))
6141 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6142 method = mono_object_get_virtual_method (target, method);
6143 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6144 if (mono_error_set_pending_exception (&error))
6146 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6149 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6150 if (mono_error_set_pending_exception (&error))
6155 ICALL_EXPORT MonoMulticastDelegate *
6156 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6159 MonoMulticastDelegate *ret;
6161 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6163 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6164 if (mono_error_set_pending_exception (&error))
6167 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6172 ICALL_EXPORT MonoReflectionMethod*
6173 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6175 MonoReflectionMethod *ret = NULL;
6177 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6178 mono_error_set_pending_exception (&error);
6184 static inline gint32
6185 mono_array_get_byte_length (MonoArray *array)
6191 klass = array->obj.vtable->klass;
6193 if (array->bounds == NULL)
6194 length = array->max_length;
6197 for (i = 0; i < klass->rank; ++ i)
6198 length *= array->bounds [i].length;
6201 switch (klass->element_class->byval_arg.type) {
6204 case MONO_TYPE_BOOLEAN:
6208 case MONO_TYPE_CHAR:
6216 return length * sizeof (gpointer);
6227 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6229 return mono_array_get_byte_length (array);
6233 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6235 return mono_array_get (array, gint8, idx);
6239 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6241 mono_array_set (array, gint8, idx, value);
6244 ICALL_EXPORT MonoBoolean
6245 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6247 guint8 *src_buf, *dest_buf;
6250 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6254 g_assert (count >= 0);
6256 /* This is called directly from the class libraries without going through the managed wrapper */
6257 MONO_CHECK_ARG_NULL (src, FALSE);
6258 MONO_CHECK_ARG_NULL (dest, FALSE);
6260 /* watch out for integer overflow */
6261 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6264 src_buf = (guint8 *)src->vector + src_offset;
6265 dest_buf = (guint8 *)dest->vector + dest_offset;
6268 memcpy (dest_buf, src_buf, count);
6270 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6275 #ifndef DISABLE_REMOTING
6276 ICALL_EXPORT MonoObject *
6277 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6280 MonoDomain *domain = mono_object_domain (this_obj);
6282 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6283 MonoTransparentProxy *tp;
6287 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6288 if (mono_error_set_pending_exception (&error))
6291 tp = (MonoTransparentProxy*) res;
6293 MONO_OBJECT_SETREF (tp, rp, rp);
6294 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6295 klass = mono_class_from_mono_type (type);
6297 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6298 mono_class_setup_vtable (klass);
6299 if (mono_class_has_failure (klass)) {
6300 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6304 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6305 if (mono_error_set_pending_exception (&error))
6307 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6308 if (mono_error_set_pending_exception (&error))
6311 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6312 if (mono_error_set_pending_exception (&error))
6317 ICALL_EXPORT MonoReflectionType *
6318 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6321 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6322 mono_error_set_pending_exception (&error);
6328 /* System.Environment */
6331 ves_icall_System_Environment_get_UserName (void)
6333 /* using glib is more portable */
6334 return mono_string_new (mono_domain_get (), g_get_user_name ());
6339 mono_icall_get_machine_name (void)
6341 #if !defined(DISABLE_SOCKETS)
6345 #if defined _SC_HOST_NAME_MAX
6346 n = sysconf (_SC_HOST_NAME_MAX);
6350 buf = g_malloc (n+1);
6352 if (gethostname (buf, n) == 0){
6354 result = mono_string_new (mono_domain_get (), buf);
6361 return mono_string_new (mono_domain_get (), "mono");
6364 #endif /* !HOST_WIN32 */
6366 ICALL_EXPORT MonoString *
6367 ves_icall_System_Environment_get_MachineName (void)
6369 return mono_icall_get_machine_name ();
6374 mono_icall_get_platform (void)
6376 #if defined(__MACH__)
6379 // Notice that the value is hidden from user code, and only exposed
6380 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6381 // define and making assumptions based on Unix/128/4 values before there
6382 // was a MacOS define. Lots of code would assume that not-Unix meant
6383 // Windows, but in this case, it would be OSX.
6391 #endif /* !HOST_WIN32 */
6394 ves_icall_System_Environment_get_Platform (void)
6396 return mono_icall_get_platform ();
6400 static inline MonoString *
6401 mono_icall_get_new_line (void)
6403 return mono_string_new (mono_domain_get (), "\n");
6405 #endif /* !HOST_WIN32 */
6407 ICALL_EXPORT MonoString *
6408 ves_icall_System_Environment_get_NewLine (void)
6410 return mono_icall_get_new_line ();
6414 static inline MonoBoolean
6415 mono_icall_is_64bit_os (void)
6417 #if SIZEOF_VOID_P == 8
6420 #if defined(HAVE_SYS_UTSNAME_H)
6421 struct utsname name;
6423 if (uname (&name) >= 0) {
6424 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6430 #endif /* !HOST_WIN32 */
6432 ICALL_EXPORT MonoBoolean
6433 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6435 return mono_icall_is_64bit_os ();
6438 ICALL_EXPORT MonoStringHandle
6439 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6443 if (utf8_name == NULL)
6444 return NULL_HANDLE_STRING;
6446 value = g_getenv (utf8_name);
6449 return NULL_HANDLE_STRING;
6451 return mono_string_new_handle (mono_domain_get (), value, error);
6455 * There is no standard way to get at environ.
6458 #ifndef __MINGW32_VERSION
6459 #if defined(__APPLE__)
6460 #if defined (TARGET_OSX)
6461 /* Apple defines this in crt_externs.h but doesn't provide that header for
6462 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6463 * in fact exist on all implementations (so far)
6465 gchar ***_NSGetEnviron(void);
6466 #define environ (*_NSGetEnviron())
6468 static char *mono_environ[1] = { NULL };
6469 #define environ mono_environ
6470 #endif /* defined (TARGET_OSX) */
6478 ICALL_EXPORT MonoArray *
6479 ves_icall_System_Environment_GetCoomandLineArgs (void)
6482 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6483 mono_error_set_pending_exception (&error);
6489 mono_icall_get_environment_variable_names (void)
6499 for (e = environ; *e != 0; ++ e)
6502 domain = mono_domain_get ();
6503 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6504 if (mono_error_set_pending_exception (&error))
6508 for (e = environ; *e != 0; ++ e) {
6509 parts = g_strsplit (*e, "=", 2);
6511 str = mono_string_new (domain, *parts);
6512 mono_array_setref (names, n, str);
6522 #endif /* !HOST_WIN32 */
6524 ICALL_EXPORT MonoArray *
6525 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6527 return mono_icall_get_environment_variable_names ();
6532 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6534 gchar *utf8_name, *utf8_value;
6537 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6538 if (mono_error_set_pending_exception (&error))
6541 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6542 g_unsetenv (utf8_name);
6547 utf8_value = mono_string_to_utf8_checked (value, &error);
6548 if (!mono_error_ok (&error)) {
6550 mono_error_set_pending_exception (&error);
6553 g_setenv (utf8_name, utf8_value, TRUE);
6556 g_free (utf8_value);
6558 #endif /* !HOST_WIN32 */
6561 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6563 mono_icall_set_environment_variable (name, value);
6567 ves_icall_System_Environment_Exit (int result)
6569 mono_environment_exitcode_set (result);
6571 /* FIXME: There are some cleanup hangs that should be worked out, but
6572 * if the program is going to exit, everything will be cleaned up when
6573 * NaCl exits anyway.
6575 #ifndef __native_client__
6576 if (!mono_runtime_try_shutdown ())
6577 mono_thread_exit ();
6579 /* Suspend all managed threads since the runtime is going away */
6580 mono_thread_suspend_all_other_threads ();
6582 mono_runtime_quit ();
6585 /* we may need to do some cleanup here... */
6589 ICALL_EXPORT MonoStringHandle
6590 ves_icall_System_Environment_GetGacPath (MonoError *error)
6592 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6596 static inline MonoString *
6597 mono_icall_get_windows_folder_path (int folder)
6599 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6600 return mono_string_new (mono_domain_get (), "");
6602 #endif /* !HOST_WIN32 */
6604 ICALL_EXPORT MonoString*
6605 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6607 return mono_icall_get_windows_folder_path (folder);
6610 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6612 mono_icall_get_logical_drives (void)
6615 gunichar2 buf [256], *ptr, *dname;
6617 guint initial_size = 127, size = 128;
6620 MonoString *drivestr;
6621 MonoDomain *domain = mono_domain_get ();
6627 while (size > initial_size) {
6628 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6629 if (size > initial_size) {
6632 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6633 initial_size = size;
6647 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6648 if (mono_error_set_pending_exception (&error))
6655 while (*u16) { u16++; len ++; }
6656 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6657 if (mono_error_set_pending_exception (&error))
6660 mono_array_setref (result, ndrives++, drivestr);
6670 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6672 ICALL_EXPORT MonoArray *
6673 ves_icall_System_Environment_GetLogicalDrives (void)
6675 return mono_icall_get_logical_drives ();
6678 ICALL_EXPORT MonoString *
6679 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6682 gunichar2 volume_name [MAX_PATH + 1];
6684 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6686 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6687 mono_error_set_pending_exception (&error);
6691 ICALL_EXPORT MonoStringHandle
6692 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6694 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6697 static const char *encodings [] = {
6699 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6700 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6701 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6703 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6704 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6705 "x_unicode_2_0_utf_7",
6707 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6708 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6710 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6713 "unicodefffe", "utf_16be",
6720 * Returns the internal codepage, if the value of "int_code_page" is
6721 * 1 at entry, and we can not compute a suitable code page number,
6722 * returns the code page as a string
6724 ICALL_EXPORT MonoString*
6725 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6730 char *codepage = NULL;
6732 int want_name = *int_code_page;
6735 *int_code_page = -1;
6737 g_get_charset (&cset);
6738 c = codepage = g_strdup (cset);
6739 for (c = codepage; *c; c++){
6740 if (isascii (*c) && isalpha (*c))
6745 /* g_print ("charset: %s\n", cset); */
6747 /* handle some common aliases */
6750 for (i = 0; p != 0; ){
6753 p = encodings [++i];
6756 if (strcmp (p, codepage) == 0){
6757 *int_code_page = code;
6760 p = encodings [++i];
6763 if (strstr (codepage, "utf_8") != NULL)
6764 *int_code_page |= 0x10000000;
6767 if (want_name && *int_code_page == -1)
6768 return mono_string_new (mono_domain_get (), cset);
6773 ICALL_EXPORT MonoBoolean
6774 ves_icall_System_Environment_get_HasShutdownStarted (void)
6776 if (mono_runtime_is_shutting_down ())
6779 if (mono_domain_is_unloading (mono_domain_get ()))
6787 mono_icall_broadcast_setting_change (void)
6791 #endif /* !HOST_WIN32 */
6794 ves_icall_System_Environment_BroadcastSettingChange (void)
6796 mono_icall_broadcast_setting_change ();
6801 ves_icall_System_Environment_get_TickCount (void)
6803 /* this will overflow after ~24 days */
6804 return (gint32) (mono_msec_boottime () & 0xffffffff);
6808 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6813 #ifndef DISABLE_REMOTING
6814 ICALL_EXPORT MonoBoolean
6815 ves_icall_IsTransparentProxy (MonoObject *proxy)
6820 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6826 ICALL_EXPORT MonoReflectionMethod *
6827 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6828 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6830 MonoReflectionMethod *ret = NULL;
6835 MonoMethod **vtable;
6836 MonoMethod *res = NULL;
6838 MONO_CHECK_ARG_NULL (rtype, NULL);
6839 MONO_CHECK_ARG_NULL (rmethod, NULL);
6841 method = rmethod->method;
6842 klass = mono_class_from_mono_type (rtype->type);
6843 mono_class_init_checked (klass, &error);
6844 if (mono_error_set_pending_exception (&error))
6847 if (MONO_CLASS_IS_INTERFACE (klass))
6850 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6853 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6854 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6860 mono_class_setup_vtable (klass);
6861 vtable = klass->vtable;
6863 if (mono_class_is_interface (method->klass)) {
6864 gboolean variance_used = FALSE;
6865 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6866 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6868 res = vtable [offs + method->slot];
6870 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6873 if (method->slot != -1)
6874 res = vtable [method->slot];
6880 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6881 mono_error_set_pending_exception (&error);
6886 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6892 klass = mono_class_from_mono_type (type->type);
6893 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6894 if (!is_ok (&error)) {
6895 mono_error_set_pending_exception (&error);
6899 mono_vtable_set_is_remote (vtable, enable);
6902 #else /* DISABLE_REMOTING */
6905 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6907 g_assert_not_reached ();
6912 ICALL_EXPORT MonoObject *
6913 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6920 domain = mono_object_domain (type);
6921 klass = mono_class_from_mono_type (type->type);
6922 mono_class_init_checked (klass, &error);
6923 if (mono_error_set_pending_exception (&error))
6926 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6927 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6931 if (klass->rank >= 1) {
6932 g_assert (klass->rank == 1);
6933 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6934 mono_error_set_pending_exception (&error);
6937 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6938 if (!is_ok (&error)) {
6939 mono_error_set_pending_exception (&error);
6942 /* Bypass remoting object creation check */
6943 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6944 mono_error_set_pending_exception (&error);
6950 ICALL_EXPORT MonoStringHandle
6951 ves_icall_System_IO_get_temp_path (MonoError *error)
6953 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6956 #ifndef PLATFORM_NO_DRIVEINFO
6957 ICALL_EXPORT MonoBoolean
6958 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
6959 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
6963 ULARGE_INTEGER wapi_free_bytes_avail;
6964 ULARGE_INTEGER wapi_total_number_of_bytes;
6965 ULARGE_INTEGER wapi_total_number_of_free_bytes;
6967 *error = ERROR_SUCCESS;
6968 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
6969 &wapi_total_number_of_free_bytes);
6972 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
6973 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
6974 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
6976 *free_bytes_avail = 0;
6977 *total_number_of_bytes = 0;
6978 *total_number_of_free_bytes = 0;
6979 *error = GetLastError ();
6985 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6986 static inline guint32
6987 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
6989 return GetDriveType (mono_string_chars (root_path_name));
6991 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6993 ICALL_EXPORT guint32
6994 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
6996 return mono_icall_drive_info_get_drive_type (root_path_name);
6999 #endif /* PLATFORM_NO_DRIVEINFO */
7001 ICALL_EXPORT gpointer
7002 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7005 gpointer result = mono_compile_method_checked (method, &error);
7006 mono_error_set_pending_exception (&error);
7010 ICALL_EXPORT MonoString *
7011 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7016 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7018 mono_icall_make_platform_path (path);
7020 mcpath = mono_string_new (mono_domain_get (), path);
7026 /* this is an icall */
7028 get_bundled_app_config (void)
7031 const gchar *app_config;
7034 gchar *config_file_name, *config_file_path;
7035 gsize len, config_file_path_length, config_ext_length;
7038 domain = mono_domain_get ();
7039 file = domain->setup->configuration_file;
7040 if (!file || file->length == 0)
7043 // Retrieve config file and remove the extension
7044 config_file_name = mono_string_to_utf8_checked (file, &error);
7045 if (mono_error_set_pending_exception (&error))
7047 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7048 if (!config_file_path)
7049 config_file_path = config_file_name;
7051 config_file_path_length = strlen (config_file_path);
7052 config_ext_length = strlen (".config");
7053 if (config_file_path_length <= config_ext_length)
7056 len = config_file_path_length - config_ext_length;
7057 module = (gchar *)g_malloc0 (len + 1);
7058 memcpy (module, config_file_path, len);
7059 // Get the config file from the module name
7060 app_config = mono_config_string_for_assembly_file (module);
7063 if (config_file_name != config_file_path)
7064 g_free (config_file_name);
7065 g_free (config_file_path);
7070 return mono_string_new (mono_domain_get (), app_config);
7073 static MonoStringHandle
7074 get_bundled_machine_config (MonoError *error)
7076 const gchar *machine_config;
7078 machine_config = mono_get_machine_config ();
7080 if (!machine_config)
7081 return NULL_HANDLE_STRING;
7083 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7086 ICALL_EXPORT MonoStringHandle
7087 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7089 return get_bundled_machine_config (error);
7093 ICALL_EXPORT MonoStringHandle
7094 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7096 return get_bundled_machine_config (error);
7099 ICALL_EXPORT MonoStringHandle
7100 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7102 return get_bundled_machine_config (error);
7106 ICALL_EXPORT MonoString *
7107 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7112 path = g_path_get_dirname (mono_get_config_dir ());
7114 mono_icall_make_platform_path (path);
7116 ipath = mono_string_new (mono_domain_get (), path);
7122 ICALL_EXPORT gboolean
7123 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7125 MonoPEResourceDataEntry *entry;
7128 if (!assembly || !result || !size)
7133 image = assembly->assembly->image;
7134 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7138 *result = mono_image_rva_map (image, entry->rde_data_offset);
7143 *size = entry->rde_size;
7148 ICALL_EXPORT MonoBoolean
7149 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7151 return mono_is_debugger_attached ();
7154 ICALL_EXPORT MonoBoolean
7155 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7157 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7158 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7164 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7166 if (mono_get_runtime_callbacks ()->debug_log)
7167 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7172 mono_icall_write_windows_debug_string (MonoString *message)
7174 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7176 #endif /* !HOST_WIN32 */
7179 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7181 mono_icall_write_windows_debug_string (message);
7184 /* Only used for value types */
7185 ICALL_EXPORT MonoObject *
7186 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7193 domain = mono_object_domain (type);
7194 klass = mono_class_from_mono_type (type->type);
7195 mono_class_init_checked (klass, &error);
7196 if (mono_error_set_pending_exception (&error))
7199 if (mono_class_is_nullable (klass))
7200 /* No arguments -> null */
7203 result = mono_object_new_checked (domain, klass, &error);
7204 mono_error_set_pending_exception (&error);
7208 ICALL_EXPORT MonoReflectionMethod *
7209 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7211 MonoReflectionMethod *ret = NULL;
7214 MonoClass *klass, *parent;
7215 MonoGenericContext *generic_inst = NULL;
7216 MonoMethod *method = m->method;
7217 MonoMethod *result = NULL;
7220 if (method->klass == NULL)
7223 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7224 MONO_CLASS_IS_INTERFACE (method->klass) ||
7225 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7228 slot = mono_method_get_vtable_slot (method);
7232 klass = method->klass;
7233 if (mono_class_is_ginst (klass)) {
7234 generic_inst = mono_class_get_context (klass);
7235 klass = mono_class_get_generic_class (klass)->container_class;
7240 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7241 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7242 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7243 or klass is the generic container class and generic_inst is the instantiation.
7245 when we go to the parent, if the parent is an open constructed type, we need to
7246 replace the type parameters by the definitions from the generic_inst, and then take it
7247 apart again into the klass and the generic_inst.
7249 For cases like this:
7250 class C<T> : B<T, int> {
7251 public override void Foo () { ... }
7253 class B<U,V> : A<HashMap<U,V>> {
7254 public override void Foo () { ... }
7257 public virtual void Foo () { ... }
7260 if at each iteration the parent isn't open, we can skip inflating it. if at some
7261 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7264 MonoGenericContext *parent_inst = NULL;
7265 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7266 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7267 if (!mono_error_ok (&error)) {
7268 mono_error_set_pending_exception (&error);
7272 if (mono_class_is_ginst (parent)) {
7273 parent_inst = mono_class_get_context (parent);
7274 parent = mono_class_get_generic_class (parent)->container_class;
7277 mono_class_setup_vtable (parent);
7278 if (parent->vtable_size <= slot)
7281 generic_inst = parent_inst;
7284 klass = klass->parent;
7287 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7288 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7289 if (!mono_error_ok (&error)) {
7290 mono_error_set_pending_exception (&error);
7294 generic_inst = NULL;
7296 if (mono_class_is_ginst (klass)) {
7297 generic_inst = mono_class_get_context (klass);
7298 klass = mono_class_get_generic_class (klass)->container_class;
7304 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7305 if (!mono_error_ok (&error)) {
7306 mono_error_set_pending_exception (&error);
7311 if (klass == method->klass)
7314 /*This is possible if definition == FALSE.
7315 * Do it here to be really sure we don't read invalid memory.
7317 if (slot >= klass->vtable_size)
7320 mono_class_setup_vtable (klass);
7322 result = klass->vtable [slot];
7323 if (result == NULL) {
7324 /* It is an abstract method */
7325 gboolean found = FALSE;
7326 gpointer iter = NULL;
7327 while ((result = mono_class_get_methods (klass, &iter))) {
7328 if (result->slot == slot) {
7333 /* found might be FALSE if we looked in an abstract class
7334 * that doesn't override an abstract method of its
7336 * abstract class Base {
7337 * public abstract void Foo ();
7339 * abstract class Derived : Base { }
7340 * class Child : Derived {
7341 * public override void Foo () { }
7344 * if m was Child.Foo and we ask for the base method,
7345 * then we get here with klass == Derived and found == FALSE
7347 /* but it shouldn't be the case that if we're looking
7348 * for the definition and didn't find a result; the
7349 * loop above should've taken us as far as we could
7351 g_assert (!(definition && !found));
7356 g_assert (result != NULL);
7358 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7359 mono_error_set_pending_exception (&error);
7363 ICALL_EXPORT MonoString*
7364 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7366 MonoMethod *method = m->method;
7368 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7373 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7375 iter->sig = *(MonoMethodSignature**)argsp;
7377 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7378 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7381 /* FIXME: it's not documented what start is exactly... */
7385 iter->args = argsp + sizeof (gpointer);
7387 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7389 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7392 ICALL_EXPORT MonoTypedRef
7393 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7395 guint32 i, arg_size;
7399 i = iter->sig->sentinelpos + iter->next_arg;
7401 g_assert (i < iter->sig->param_count);
7403 res.type = iter->sig->params [i];
7404 res.klass = mono_class_from_mono_type (res.type);
7405 arg_size = mono_type_stack_size (res.type, &align);
7406 #if defined(__arm__) || defined(__mips__)
7407 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7409 res.value = iter->args;
7410 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7411 /* Values are stored as 8 byte register sized objects, but 'value'
7412 * is dereferenced as a pointer in other routines.
7414 res.value = (char*)res.value + 4;
7416 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7417 if (arg_size <= sizeof (gpointer)) {
7419 int padding = arg_size - mono_type_size (res.type, &dummy);
7420 res.value = (guint8*)res.value + padding;
7423 iter->args = (char*)iter->args + arg_size;
7426 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7431 ICALL_EXPORT MonoTypedRef
7432 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7434 guint32 i, arg_size;
7438 i = iter->sig->sentinelpos + iter->next_arg;
7440 g_assert (i < iter->sig->param_count);
7442 while (i < iter->sig->param_count) {
7443 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7445 res.type = iter->sig->params [i];
7446 res.klass = mono_class_from_mono_type (res.type);
7447 /* FIXME: endianess issue... */
7448 arg_size = mono_type_stack_size (res.type, &align);
7449 #if defined(__arm__) || defined(__mips__)
7450 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7452 res.value = iter->args;
7453 iter->args = (char*)iter->args + arg_size;
7455 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7458 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7466 ICALL_EXPORT MonoType*
7467 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7471 i = iter->sig->sentinelpos + iter->next_arg;
7473 g_assert (i < iter->sig->param_count);
7475 return iter->sig->params [i];
7478 ICALL_EXPORT MonoObject*
7479 mono_TypedReference_ToObject (MonoTypedRef* tref)
7482 MonoObject *result = NULL;
7483 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7484 MonoObject** objp = (MonoObject **)tref->value;
7488 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7489 mono_error_set_pending_exception (&error);
7493 ICALL_EXPORT MonoTypedRef
7494 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7497 MonoReflectionField *f;
7499 MonoType *ftype = NULL;
7503 memset (&res, 0, sizeof (res));
7506 g_assert (mono_array_length (fields) > 0);
7508 klass = target->vtable->klass;
7510 for (i = 0; i < mono_array_length (fields); ++i) {
7511 f = mono_array_get (fields, MonoReflectionField*, i);
7513 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7516 if (f->field->parent != klass) {
7517 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7521 p = (guint8*)target + f->field->offset;
7523 p += f->field->offset - sizeof (MonoObject);
7524 klass = mono_class_from_mono_type (f->field->type);
7525 ftype = f->field->type;
7529 res.klass = mono_class_from_mono_type (ftype);
7536 prelink_method (MonoMethod *method, MonoError *error)
7538 const char *exc_class, *exc_arg;
7540 mono_error_init (error);
7541 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7543 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7545 mono_error_set_exception_instance (error,
7546 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7549 /* create the wrapper, too? */
7553 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7557 prelink_method (method->method, &error);
7558 mono_error_set_pending_exception (&error);
7562 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7565 MonoClass *klass = mono_class_from_mono_type (type->type);
7567 gpointer iter = NULL;
7569 mono_class_init_checked (klass, &error);
7570 if (mono_error_set_pending_exception (&error))
7573 while ((m = mono_class_get_methods (klass, &iter))) {
7574 prelink_method (m, &error);
7575 if (mono_error_set_pending_exception (&error))
7580 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7582 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7583 gint32 const **exponents,
7584 gunichar2 const **digitLowerTable,
7585 gunichar2 const **digitUpperTable,
7586 gint64 const **tenPowersList,
7587 gint32 const **decHexDigits)
7589 *mantissas = Formatter_MantissaBitsTable;
7590 *exponents = Formatter_TensExponentTable;
7591 *digitLowerTable = Formatter_DigitLowerTable;
7592 *digitUpperTable = Formatter_DigitUpperTable;
7593 *tenPowersList = Formatter_TenPowersList;
7594 *decHexDigits = Formatter_DecHexDigits;
7598 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7599 * and avoid useless allocations.
7602 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7604 MonoReflectionType *rt;
7608 mono_error_init (error);
7609 for (i = 0; i < type->num_mods; ++i) {
7610 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7615 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7616 return_val_if_nok (error, NULL);
7618 for (i = 0; i < type->num_mods; ++i) {
7619 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7620 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7621 return_val_if_nok (error, NULL);
7623 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7624 return_val_if_nok (error, NULL);
7626 mono_array_setref (res, count, rt);
7633 ICALL_EXPORT MonoArray*
7634 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7637 MonoType *type = param->ClassImpl->type;
7638 MonoClass *member_class = mono_object_class (param->MemberImpl);
7639 MonoMethod *method = NULL;
7642 MonoMethodSignature *sig;
7645 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7646 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7647 method = rmethod->method;
7648 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7649 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7650 if (!(method = prop->property->get))
7651 method = prop->property->set;
7654 char *type_name = mono_type_get_full_name (member_class);
7655 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7656 MonoException *ex = mono_get_exception_not_supported (msg);
7659 mono_set_pending_exception (ex);
7663 image = method->klass->image;
7664 pos = param->PositionImpl;
7665 sig = mono_method_signature (method);
7669 type = sig->params [pos];
7671 res = type_array_from_modifiers (image, type, optional, &error);
7672 mono_error_set_pending_exception (&error);
7677 get_property_type (MonoProperty *prop)
7679 MonoMethodSignature *sig;
7681 sig = mono_method_signature (prop->get);
7683 } else if (prop->set) {
7684 sig = mono_method_signature (prop->set);
7685 return sig->params [sig->param_count - 1];
7690 ICALL_EXPORT MonoArray*
7691 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7694 MonoType *type = get_property_type (property->property);
7695 MonoImage *image = property->klass->image;
7700 res = type_array_from_modifiers (image, type, optional, &error);
7701 mono_error_set_pending_exception (&error);
7706 *Construct a MonoType suited to be used to decode a constant blob object.
7708 * @type is the target type which will be constructed
7709 * @blob_type is the blob type, for example, that comes from the constant table
7710 * @real_type is the expected constructed type.
7713 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7715 type->type = blob_type;
7716 type->data.klass = NULL;
7717 if (blob_type == MONO_TYPE_CLASS)
7718 type->data.klass = mono_defaults.object_class;
7719 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7720 /* For enums, we need to use the base type */
7721 type->type = MONO_TYPE_VALUETYPE;
7722 type->data.klass = mono_class_from_mono_type (real_type);
7724 type->data.klass = mono_class_from_mono_type (real_type);
7727 ICALL_EXPORT MonoObject*
7728 property_info_get_default_value (MonoReflectionProperty *property)
7732 MonoProperty *prop = property->property;
7733 MonoType *type = get_property_type (prop);
7734 MonoDomain *domain = mono_object_domain (property);
7735 MonoTypeEnum def_type;
7736 const char *def_value;
7739 mono_class_init (prop->parent);
7741 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7742 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7746 def_value = mono_class_get_property_default_value (prop, &def_type);
7748 mono_type_from_blob_type (&blob_type, def_type, type);
7749 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7751 mono_error_set_pending_exception (&error);
7755 ICALL_EXPORT MonoBoolean
7756 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7759 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7760 MonoCustomAttrInfo *cinfo;
7763 mono_class_init_checked (attr_class, &error);
7764 if (mono_error_set_pending_exception (&error))
7767 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7768 if (!is_ok (&error)) {
7769 mono_error_set_pending_exception (&error);
7774 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7776 mono_custom_attrs_free (cinfo);
7780 ICALL_EXPORT MonoArray*
7781 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7783 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7788 mono_class_init_checked (attr_class, &error);
7789 if (mono_error_set_pending_exception (&error))
7793 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7794 if (!mono_error_ok (&error)) {
7795 mono_error_set_pending_exception (&error);
7802 ICALL_EXPORT MonoArray*
7803 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7807 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7808 mono_error_set_pending_exception (&error);
7813 ICALL_EXPORT MonoStringHandle
7814 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7817 MonoStringHandle display_name;
7819 mono_error_init (error);
7820 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7821 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7823 return display_name;
7826 ICALL_EXPORT MonoString*
7827 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7830 MonoString *message;
7834 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7835 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7838 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7840 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7841 if (mono_error_set_pending_exception (&error))
7849 static inline gint32
7850 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7852 return WAIT_TIMEOUT;
7854 #endif /* !HOST_WIN32 */
7857 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7859 return mono_icall_wait_for_input_idle (handle, milliseconds);
7863 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7865 return mono_process_current_pid ();
7868 ICALL_EXPORT MonoBoolean
7869 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7881 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7883 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7887 ICALL_EXPORT MonoObject*
7888 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7890 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7895 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7897 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7901 ICALL_EXPORT MonoObject*
7902 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7904 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7908 ICALL_EXPORT MonoBoolean
7909 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7911 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7916 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7918 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7922 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7924 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7929 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7931 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7935 ICALL_EXPORT mono_unichar2*
7936 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7938 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7945 #ifndef DISABLE_ICALL_TABLES
7947 #define ICALL_TYPE(id,name,first)
7948 #define ICALL(id,name,func) Icall_ ## id,
7949 #define HANDLES(inner) inner
7952 #include "metadata/icall-def.h"
7958 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7959 #define ICALL(id,name,func)
7961 #define HANDLES(inner) inner
7963 #include "metadata/icall-def.h"
7969 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7970 #define ICALL(id,name,func)
7972 #define HANDLES(inner) inner
7974 guint16 first_icall;
7977 static const IcallTypeDesc
7978 icall_type_descs [] = {
7979 #include "metadata/icall-def.h"
7983 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7986 #define HANDLES(inner) inner
7988 #define ICALL_TYPE(id,name,first)
7991 #ifdef HAVE_ARRAY_ELEM_INIT
7992 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7993 #define MSGSTRFIELD1(line) str##line
7995 static const struct msgstrtn_t {
7996 #define ICALL(id,name,func)
7998 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7999 #include "metadata/icall-def.h"
8001 } icall_type_names_str = {
8002 #define ICALL_TYPE(id,name,first) (name),
8003 #include "metadata/icall-def.h"
8006 static const guint16 icall_type_names_idx [] = {
8007 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8008 #include "metadata/icall-def.h"
8011 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8013 static const struct msgstr_t {
8015 #define ICALL_TYPE(id,name,first)
8016 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8017 #include "metadata/icall-def.h"
8019 } icall_names_str = {
8020 #define ICALL(id,name,func) (name),
8021 #include "metadata/icall-def.h"
8024 static const guint16 icall_names_idx [] = {
8025 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8026 #include "metadata/icall-def.h"
8029 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8035 #define ICALL_TYPE(id,name,first) name,
8036 #define ICALL(id,name,func)
8037 static const char* const
8038 icall_type_names [] = {
8039 #include "metadata/icall-def.h"
8043 #define icall_type_name_get(id) (icall_type_names [(id)])
8047 #define ICALL_TYPE(id,name,first)
8048 #define ICALL(id,name,func) name,
8049 static const char* const
8051 #include "metadata/icall-def.h"
8054 #define icall_name_get(id) icall_names [(id)]
8056 #endif /* !HAVE_ARRAY_ELEM_INIT */
8059 #define HANDLES(inner) inner
8062 #define ICALL_TYPE(id,name,first)
8063 #define ICALL(id,name,func) func,
8064 static const gconstpointer
8065 icall_functions [] = {
8066 #include "metadata/icall-def.h"
8070 #ifdef ENABLE_ICALL_SYMBOL_MAP
8072 #define HANDLES(inner) inner
8075 #define ICALL_TYPE(id,name,first)
8076 #define ICALL(id,name,func) #func,
8077 static const gconstpointer
8078 icall_symbols [] = {
8079 #include "metadata/icall-def.h"
8086 #define ICALL_TYPE(id,name,first)
8087 #define ICALL(id,name,func) 0,
8089 #define HANDLES(inner) 1,
8091 icall_uses_handles [] = {
8092 #include "metadata/icall-def.h"
8097 #endif /* DISABLE_ICALL_TABLES */
8099 static mono_mutex_t icall_mutex;
8100 static GHashTable *icall_hash = NULL;
8101 static GHashTable *jit_icall_hash_name = NULL;
8102 static GHashTable *jit_icall_hash_addr = NULL;
8105 mono_icall_init (void)
8107 #ifndef DISABLE_ICALL_TABLES
8110 /* check that tables are sorted: disable in release */
8113 const char *prev_class = NULL;
8114 const char *prev_method;
8116 for (i = 0; i < Icall_type_num; ++i) {
8117 const IcallTypeDesc *desc;
8120 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8121 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8122 prev_class = icall_type_name_get (i);
8123 desc = &icall_type_descs [i];
8124 num_icalls = icall_desc_num_icalls (desc);
8125 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8126 for (j = 0; j < num_icalls; ++j) {
8127 const char *methodn = icall_name_get (desc->first_icall + j);
8128 if (prev_method && strcmp (prev_method, methodn) >= 0)
8129 g_print ("method %s should come before method %s\n", methodn, prev_method);
8130 prev_method = methodn;
8136 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8137 mono_os_mutex_init (&icall_mutex);
8141 mono_icall_lock (void)
8143 mono_locks_os_acquire (&icall_mutex, IcallLock);
8147 mono_icall_unlock (void)
8149 mono_locks_os_release (&icall_mutex, IcallLock);
8153 mono_icall_cleanup (void)
8155 g_hash_table_destroy (icall_hash);
8156 g_hash_table_destroy (jit_icall_hash_name);
8157 g_hash_table_destroy (jit_icall_hash_addr);
8158 mono_os_mutex_destroy (&icall_mutex);
8162 * mono_add_internal_call:
8163 * @name: method specification to surface to the managed world
8164 * @method: pointer to a C method to invoke when the method is called
8166 * This method surfaces the C function pointed by @method as a method
8167 * that has been surfaced in managed code with the method specified in
8168 * @name as an internal call.
8170 * Internal calls are surfaced to all app domains loaded and they are
8171 * accessibly by a type with the specified name.
8173 * You must provide a fully qualified type name, that is namespaces
8174 * and type name, followed by a colon and the method name, with an
8175 * optional signature to bind.
8177 * For example, the following are all valid declarations:
8179 * "MyApp.Services.ScriptService:Accelerate"
8180 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8182 * You use method parameters in cases where there might be more than
8183 * one surface method to managed code. That way you can register different
8184 * internal calls for different method overloads.
8186 * The internal calls are invoked with no marshalling. This means that .NET
8187 * types like System.String are exposed as `MonoString *` parameters. This is
8188 * different than the way that strings are surfaced in P/Invoke.
8190 * For more information on how the parameters are marshalled, see the
8191 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8194 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8195 * reference for more information on the format of method descriptions.
8198 mono_add_internal_call (const char *name, gconstpointer method)
8202 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8204 mono_icall_unlock ();
8207 #ifndef DISABLE_ICALL_TABLES
8209 #ifdef HAVE_ARRAY_ELEM_INIT
8211 compare_method_imap (const void *key, const void *elem)
8213 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8214 return strcmp (key, method_name);
8218 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8220 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);
8223 return (nameslot - &icall_names_idx [0]);
8227 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8229 gsize slotnum = find_slot_icall (imap, name);
8232 return (gboolean)icall_uses_handles [slotnum];
8236 find_method_icall (const IcallTypeDesc *imap, const char *name)
8238 gsize slotnum = find_slot_icall (imap, name);
8241 return (gpointer)icall_functions [slotnum];
8245 compare_class_imap (const void *key, const void *elem)
8247 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8248 return strcmp (key, class_name);
8251 static const IcallTypeDesc*
8252 find_class_icalls (const char *name)
8254 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);
8257 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8260 #else /* HAVE_ARRAY_ELEM_INIT */
8263 compare_method_imap (const void *key, const void *elem)
8265 const char** method_name = (const char**)elem;
8266 return strcmp (key, *method_name);
8270 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8272 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8275 return nameslot - icall_names;
8279 find_method_icall (const IcallTypeDesc *imap, const char *name)
8281 gsize slotnum = find_slot_icall (imap, name);
8284 return (gpointer)icall_functions [slotnum];
8288 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8290 gsize slotnum = find_slot_icall (imap, name);
8293 return (gboolean)icall_uses_handles [slotnum];
8297 compare_class_imap (const void *key, const void *elem)
8299 const char** class_name = (const char**)elem;
8300 return strcmp (key, *class_name);
8303 static const IcallTypeDesc*
8304 find_class_icalls (const char *name)
8306 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8309 return &icall_type_descs [nameslot - icall_type_names];
8312 #endif /* HAVE_ARRAY_ELEM_INIT */
8314 #endif /* DISABLE_ICALL_TABLES */
8317 * we should probably export this as an helper (handle nested types).
8318 * Returns the number of chars written in buf.
8321 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8323 int nspacelen, cnamelen;
8324 nspacelen = strlen (klass->name_space);
8325 cnamelen = strlen (klass->name);
8326 if (nspacelen + cnamelen + 2 > bufsize)
8329 memcpy (buf, klass->name_space, nspacelen);
8330 buf [nspacelen ++] = '.';
8332 memcpy (buf + nspacelen, klass->name, cnamelen);
8333 buf [nspacelen + cnamelen] = 0;
8334 return nspacelen + cnamelen;
8337 #ifdef DISABLE_ICALL_TABLES
8339 no_icall_table (void)
8341 g_assert_not_reached ();
8346 * mono_lookup_internal_call_full:
8347 * @method: the method to look up
8348 * @uses_handles: out argument if method needs handles around managed objects.
8350 * Returns a pointer to the icall code for the given method. If
8351 * uses_handles is not NULL, it will be set to TRUE if the method
8352 * needs managed objects wrapped using the infrastructure in handle.h
8354 * If the method is not found, warns and returns NULL.
8357 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8362 int typelen = 0, mlen, siglen;
8364 #ifndef DISABLE_ICALL_TABLES
8365 const IcallTypeDesc *imap = NULL;
8368 g_assert (method != NULL);
8370 if (method->is_inflated)
8371 method = ((MonoMethodInflated *) method)->declaring;
8373 if (method->klass->nested_in) {
8374 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8378 mname [pos++] = '/';
8381 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8387 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8392 #ifndef DISABLE_ICALL_TABLES
8393 imap = find_class_icalls (mname);
8396 mname [typelen] = ':';
8397 mname [typelen + 1] = ':';
8399 mlen = strlen (method->name);
8400 memcpy (mname + typelen + 2, method->name, mlen);
8401 sigstart = mname + typelen + 2 + mlen;
8404 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8405 siglen = strlen (tmpsig);
8406 if (typelen + mlen + siglen + 6 > sizeof (mname))
8409 memcpy (sigstart + 1, tmpsig, siglen);
8410 sigstart [siglen + 1] = ')';
8411 sigstart [siglen + 2] = 0;
8416 res = g_hash_table_lookup (icall_hash, mname);
8419 *uses_handles = FALSE;
8420 mono_icall_unlock ();;
8423 /* try without signature */
8425 res = g_hash_table_lookup (icall_hash, mname);
8428 *uses_handles = FALSE;
8429 mono_icall_unlock ();
8433 #ifdef DISABLE_ICALL_TABLES
8434 mono_icall_unlock ();
8435 /* Fail only when the result is actually used */
8436 /* mono_marshal_get_native_wrapper () depends on this */
8437 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8438 return ves_icall_System_String_ctor_RedirectToCreateString;
8440 return no_icall_table;
8442 /* it wasn't found in the static call tables */
8445 *uses_handles = FALSE;
8446 mono_icall_unlock ();
8449 res = find_method_icall (imap, sigstart - mlen);
8452 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8453 mono_icall_unlock ();
8456 /* try _with_ signature */
8458 res = find_method_icall (imap, sigstart - mlen);
8461 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8462 mono_icall_unlock ();
8466 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8467 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8468 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8469 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8470 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");
8471 g_print ("If you see other errors or faults after this message they are probably related\n");
8472 g_print ("and you need to fix your mono install first.\n");
8474 mono_icall_unlock ();
8481 mono_lookup_internal_call (MonoMethod *method)
8483 return mono_lookup_internal_call_full (method, NULL);
8486 #ifdef ENABLE_ICALL_SYMBOL_MAP
8488 func_cmp (gconstpointer key, gconstpointer p)
8490 return (gsize)key - (gsize)*(gsize*)p;
8495 * mono_lookup_icall_symbol:
8497 * Given the icall METHOD, returns its C symbol.
8500 mono_lookup_icall_symbol (MonoMethod *m)
8502 #ifdef DISABLE_ICALL_TABLES
8503 g_assert_not_reached ();
8506 #ifdef ENABLE_ICALL_SYMBOL_MAP
8510 static gconstpointer *functions_sorted;
8511 static const char**symbols_sorted;
8512 static gboolean inited;
8517 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8518 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8519 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8520 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8521 /* Bubble sort the two arrays */
8525 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8526 if (functions_sorted [i] > functions_sorted [i + 1]) {
8529 tmp = functions_sorted [i];
8530 functions_sorted [i] = functions_sorted [i + 1];
8531 functions_sorted [i + 1] = tmp;
8532 tmp = symbols_sorted [i];
8533 symbols_sorted [i] = symbols_sorted [i + 1];
8534 symbols_sorted [i + 1] = tmp;
8541 func = mono_lookup_internal_call (m);
8544 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8548 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8550 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8551 g_assert_not_reached ();
8558 type_from_typename (char *type_name)
8560 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8562 if (!strcmp (type_name, "int"))
8563 klass = mono_defaults.int_class;
8564 else if (!strcmp (type_name, "ptr"))
8565 klass = mono_defaults.int_class;
8566 else if (!strcmp (type_name, "void"))
8567 klass = mono_defaults.void_class;
8568 else if (!strcmp (type_name, "int32"))
8569 klass = mono_defaults.int32_class;
8570 else if (!strcmp (type_name, "uint32"))
8571 klass = mono_defaults.uint32_class;
8572 else if (!strcmp (type_name, "int8"))
8573 klass = mono_defaults.sbyte_class;
8574 else if (!strcmp (type_name, "uint8"))
8575 klass = mono_defaults.byte_class;
8576 else if (!strcmp (type_name, "int16"))
8577 klass = mono_defaults.int16_class;
8578 else if (!strcmp (type_name, "uint16"))
8579 klass = mono_defaults.uint16_class;
8580 else if (!strcmp (type_name, "long"))
8581 klass = mono_defaults.int64_class;
8582 else if (!strcmp (type_name, "ulong"))
8583 klass = mono_defaults.uint64_class;
8584 else if (!strcmp (type_name, "float"))
8585 klass = mono_defaults.single_class;
8586 else if (!strcmp (type_name, "double"))
8587 klass = mono_defaults.double_class;
8588 else if (!strcmp (type_name, "object"))
8589 klass = mono_defaults.object_class;
8590 else if (!strcmp (type_name, "obj"))
8591 klass = mono_defaults.object_class;
8592 else if (!strcmp (type_name, "string"))
8593 klass = mono_defaults.string_class;
8594 else if (!strcmp (type_name, "bool"))
8595 klass = mono_defaults.boolean_class;
8596 else if (!strcmp (type_name, "boolean"))
8597 klass = mono_defaults.boolean_class;
8599 g_error ("%s", type_name);
8600 g_assert_not_reached ();
8602 return &klass->byval_arg;
8606 * LOCKING: Take the corlib image lock.
8608 MonoMethodSignature*
8609 mono_create_icall_signature (const char *sigstr)
8614 MonoMethodSignature *res, *res2;
8615 MonoImage *corlib = mono_defaults.corlib;
8617 mono_image_lock (corlib);
8618 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8619 mono_image_unlock (corlib);
8624 parts = g_strsplit (sigstr, " ", 256);
8633 res = mono_metadata_signature_alloc (corlib, len - 1);
8638 * Under windows, the default pinvoke calling convention is STDCALL but
8641 res->call_convention = MONO_CALL_C;
8644 res->ret = type_from_typename (parts [0]);
8645 for (i = 1; i < len; ++i) {
8646 res->params [i - 1] = type_from_typename (parts [i]);
8651 mono_image_lock (corlib);
8652 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8654 res = res2; /*Value is allocated in the image pool*/
8656 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8657 mono_image_unlock (corlib);
8663 mono_find_jit_icall_by_name (const char *name)
8665 MonoJitICallInfo *info;
8666 g_assert (jit_icall_hash_name);
8669 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8670 mono_icall_unlock ();
8675 mono_find_jit_icall_by_addr (gconstpointer addr)
8677 MonoJitICallInfo *info;
8678 g_assert (jit_icall_hash_addr);
8681 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8682 mono_icall_unlock ();
8688 * mono_get_jit_icall_info:
8690 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8691 * caller should access it while holding the icall lock.
8694 mono_get_jit_icall_info (void)
8696 return jit_icall_hash_name;
8700 * mono_lookup_jit_icall_symbol:
8702 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8705 mono_lookup_jit_icall_symbol (const char *name)
8707 MonoJitICallInfo *info;
8708 const char *res = NULL;
8711 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8713 res = info->c_symbol;
8714 mono_icall_unlock ();
8719 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8722 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8723 mono_icall_unlock ();
8727 * 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
8728 * icalls without wrappers in some cases.
8731 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8733 MonoJitICallInfo *info;
8740 if (!jit_icall_hash_name) {
8741 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8742 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8745 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8746 g_warning ("jit icall already defined \"%s\"\n", name);
8747 g_assert_not_reached ();
8750 info = g_new0 (MonoJitICallInfo, 1);
8755 info->c_symbol = c_symbol;
8756 info->no_raise = no_raise;
8759 info->wrapper = func;
8761 info->wrapper = NULL;
8764 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8765 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8767 mono_icall_unlock ();
8772 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8774 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);