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 current = (guint8 *)&stack_addr;
1002 if (current > stack_addr) {
1003 if ((current - stack_addr) < min_size)
1006 if (current - (stack_addr - stack_size) < min_size)
1013 ICALL_EXPORT MonoObject *
1014 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1017 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1018 mono_error_set_pending_exception (&error);
1024 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1028 MonoObject **values = NULL;
1031 gint32 result = (int)(gsize)mono_defaults.int32_class;
1032 MonoClassField* field;
1035 klass = mono_object_class (this_obj);
1037 if (mono_class_num_fields (klass) == 0)
1041 * Compute the starting value of the hashcode for fields of primitive
1042 * types, and return the remaining fields in an array to the managed side.
1043 * This way, we can avoid costly reflection operations in managed code.
1046 while ((field = mono_class_get_fields (klass, &iter))) {
1047 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1049 if (mono_field_is_deleted (field))
1051 /* FIXME: Add more types */
1052 switch (field->type->type) {
1054 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1056 case MONO_TYPE_STRING: {
1058 s = *(MonoString**)((guint8*)this_obj + field->offset);
1060 result ^= mono_string_hash (s);
1065 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1066 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1067 if (!is_ok (&error)) {
1068 mono_error_set_pending_exception (&error);
1071 values [count++] = o;
1077 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1078 if (mono_error_set_pending_exception (&error))
1080 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1081 for (i = 0; i < count; ++i)
1082 mono_array_setref (*fields, i, values [i]);
1089 ICALL_EXPORT MonoBoolean
1090 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1094 MonoObject **values = NULL;
1096 MonoClassField* field;
1100 MONO_CHECK_ARG_NULL (that, FALSE);
1102 if (this_obj->vtable != that->vtable)
1105 klass = mono_object_class (this_obj);
1107 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1108 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1111 * Do the comparison for fields of primitive type and return a result if
1112 * possible. Otherwise, return the remaining fields in an array to the
1113 * managed side. This way, we can avoid costly reflection operations in
1118 while ((field = mono_class_get_fields (klass, &iter))) {
1119 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1121 if (mono_field_is_deleted (field))
1123 /* FIXME: Add more types */
1124 switch (field->type->type) {
1127 case MONO_TYPE_BOOLEAN:
1128 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1133 case MONO_TYPE_CHAR:
1134 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1139 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1144 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1148 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1152 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1157 case MONO_TYPE_STRING: {
1158 MonoString *s1, *s2;
1159 guint32 s1len, s2len;
1160 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1161 s2 = *(MonoString**)((guint8*)that + field->offset);
1164 if ((s1 == NULL) || (s2 == NULL))
1166 s1len = mono_string_length (s1);
1167 s2len = mono_string_length (s2);
1171 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1177 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1178 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1179 if (!is_ok (&error)) {
1180 mono_error_set_pending_exception (&error);
1183 values [count++] = o;
1184 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1185 if (!is_ok (&error)) {
1186 mono_error_set_pending_exception (&error);
1189 values [count++] = o;
1192 if (klass->enumtype)
1193 /* enums only have one non-static field */
1199 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1200 if (mono_error_set_pending_exception (&error))
1202 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1203 for (i = 0; i < count; ++i)
1204 mono_array_setref_fast (*fields, i, values [i]);
1211 ICALL_EXPORT MonoReflectionType *
1212 ves_icall_System_Object_GetType (MonoObject *obj)
1215 MonoReflectionType *ret;
1216 #ifndef DISABLE_REMOTING
1217 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1218 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1221 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1223 mono_error_set_pending_exception (&error);
1228 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1230 MonoMethod **dest = (MonoMethod **)data;
1232 /* skip unmanaged frames */
1237 if (!strcmp (m->klass->name_space, "System.Reflection"))
1246 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1248 MonoMethod **dest = (MonoMethod **)data;
1250 /* skip unmanaged frames */
1254 if (m->wrapper_type != MONO_WRAPPER_NONE)
1262 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1273 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1275 MonoMethod **dest = (MonoMethod **)data;
1277 /* skip unmanaged frames */
1281 if (m->wrapper_type != MONO_WRAPPER_NONE)
1289 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1290 || (!strcmp (m->klass->name_space, "System"))))
1300 static MonoReflectionType *
1301 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1303 MonoMethod *m, *dest;
1305 MonoType *type = NULL;
1306 MonoAssembly *assembly = NULL;
1307 gboolean type_resolve = FALSE;
1308 MonoImage *rootimage = NULL;
1310 mono_error_init (error);
1313 * We must compute the calling assembly as type loading must happen under a metadata context.
1314 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1315 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1317 m = mono_method_get_last_managed ();
1319 if (m && m->klass->image != mono_defaults.corlib) {
1320 /* Happens with inlining */
1322 /* Ugly hack: type_from_parsed_name is called from
1323 * System.Type.internal_from_name, which is called most
1324 * directly from System.Type.GetType(string,bool,bool) but
1325 * also indirectly from places such as
1326 * System.Type.GetType(string,func,func) (via
1327 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1328 * so we need to skip over all of those to find the true caller.
1330 * It would be nice if we had stack marks.
1332 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1338 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1339 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1340 * to crash. This only seems to happen in some strange remoting
1341 * scenarios and I was unable to figure out what's happening there.
1342 * Dec 10, 2005 - Martin.
1346 assembly = dest->klass->image->assembly;
1347 type_resolve = TRUE;
1348 rootimage = assembly->image;
1350 g_warning (G_STRLOC);
1352 *caller_assembly = assembly;
1354 if (info->assembly.name)
1355 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1358 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1359 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1360 return_val_if_nok (error, NULL);
1364 // Say we're looking for System.Generic.Dict<int, Local>
1365 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1366 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1367 // is messed up when we go to construct the Local as the type arg...
1369 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1370 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1371 if (!info->assembly.name && !type) {
1373 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1374 return_val_if_nok (error, NULL);
1376 if (assembly && !type && type_resolve) {
1377 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1378 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1379 return_val_if_nok (error, NULL);
1385 return mono_type_get_object_checked (mono_domain_get (), type, error);
1388 ICALL_EXPORT MonoReflectionType*
1389 ves_icall_System_Type_internal_from_name (MonoString *name,
1390 MonoBoolean throwOnError,
1391 MonoBoolean ignoreCase)
1394 MonoTypeNameParse info;
1395 MonoReflectionType *type = NULL;
1397 MonoAssembly *caller_assembly;
1399 char *str = mono_string_to_utf8_checked (name, &error);
1400 if (!is_ok (&error))
1403 parsedOk = mono_reflection_parse_type (str, &info);
1405 /* mono_reflection_parse_type() mangles the string */
1407 mono_reflection_free_type_info (&info);
1409 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1413 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1415 if (!is_ok (&error)) {
1416 mono_reflection_free_type_info (&info);
1422 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1424 if (info.assembly.name)
1425 aname = mono_stringify_assembly_name (&info.assembly);
1426 else if (caller_assembly)
1427 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1429 aname = g_strdup ("");
1430 mono_error_set_type_load_name (&error, tname, aname, "");
1432 mono_reflection_free_type_info (&info);
1438 if (!is_ok (&error)) {
1440 mono_error_set_pending_exception (&error);
1442 mono_error_cleanup (&error);
1450 ICALL_EXPORT MonoReflectionType*
1451 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1454 MonoReflectionType *ret;
1455 MonoDomain *domain = mono_domain_get ();
1457 ret = mono_type_get_object_checked (domain, handle, &error);
1458 mono_error_set_pending_exception (&error);
1463 ICALL_EXPORT MonoType*
1464 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1466 return mono_class_get_type (klass);
1470 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1472 g_ptr_array_free (ptr_array, TRUE);
1476 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1482 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1485 char *res = mono_string_to_utf8_checked (s, &error);
1486 mono_error_set_pending_exception (&error);
1490 /* System.TypeCode */
1509 TYPECODE_STRING = 18
1512 ICALL_EXPORT guint32
1513 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1515 int t = type->type->type;
1517 if (type->type->byref)
1518 return TYPECODE_OBJECT;
1522 case MONO_TYPE_VOID:
1523 return TYPECODE_OBJECT;
1524 case MONO_TYPE_BOOLEAN:
1525 return TYPECODE_BOOLEAN;
1527 return TYPECODE_BYTE;
1529 return TYPECODE_SBYTE;
1531 return TYPECODE_UINT16;
1533 return TYPECODE_INT16;
1534 case MONO_TYPE_CHAR:
1535 return TYPECODE_CHAR;
1539 return TYPECODE_OBJECT;
1541 return TYPECODE_UINT32;
1543 return TYPECODE_INT32;
1545 return TYPECODE_UINT64;
1547 return TYPECODE_INT64;
1549 return TYPECODE_SINGLE;
1551 return TYPECODE_DOUBLE;
1552 case MONO_TYPE_VALUETYPE: {
1553 MonoClass *klass = type->type->data.klass;
1555 if (klass->enumtype) {
1556 t = mono_class_enum_basetype (klass)->type;
1558 } else if (mono_is_corlib_image (klass->image)) {
1559 if (strcmp (klass->name_space, "System") == 0) {
1560 if (strcmp (klass->name, "Decimal") == 0)
1561 return TYPECODE_DECIMAL;
1562 else if (strcmp (klass->name, "DateTime") == 0)
1563 return TYPECODE_DATETIME;
1566 return TYPECODE_OBJECT;
1568 case MONO_TYPE_STRING:
1569 return TYPECODE_STRING;
1570 case MONO_TYPE_SZARRAY:
1571 case MONO_TYPE_ARRAY:
1572 case MONO_TYPE_OBJECT:
1574 case MONO_TYPE_MVAR:
1575 case MONO_TYPE_TYPEDBYREF:
1576 return TYPECODE_OBJECT;
1577 case MONO_TYPE_CLASS:
1579 MonoClass *klass = type->type->data.klass;
1580 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1581 if (strcmp (klass->name, "DBNull") == 0)
1582 return TYPECODE_DBNULL;
1585 return TYPECODE_OBJECT;
1586 case MONO_TYPE_GENERICINST:
1587 return TYPECODE_OBJECT;
1589 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1595 mono_type_is_primitive (MonoType *type)
1597 return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
1598 type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
1602 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1604 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1605 return mono_class_enum_basetype (type->data.klass);
1606 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1607 return mono_class_enum_basetype (type->data.generic_class->container_class);
1611 ICALL_EXPORT guint32
1612 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1617 g_assert (type != NULL);
1619 klass = mono_class_from_mono_type (type->type);
1620 klassc = mono_class_from_mono_type (c->type);
1622 if (type->type->byref ^ c->type->byref)
1625 if (type->type->byref) {
1626 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1627 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1629 klass = mono_class_from_mono_type (t);
1630 klassc = mono_class_from_mono_type (ot);
1632 if (mono_type_is_primitive (t)) {
1633 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1634 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1635 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1636 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1637 return t->type == ot->type;
1639 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1642 if (klass->valuetype)
1643 return klass == klassc;
1644 return klass->valuetype == klassc->valuetype;
1647 return mono_class_is_assignable_from (klass, klassc);
1650 ICALL_EXPORT guint32
1651 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1654 MonoClass *klass = mono_class_from_mono_type (type->type);
1655 mono_class_init_checked (klass, &error);
1656 if (!is_ok (&error)) {
1657 mono_error_set_pending_exception (&error);
1660 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1661 mono_error_set_pending_exception (&error);
1665 ICALL_EXPORT guint32
1666 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1668 MonoClass *klass = mono_class_from_mono_type (type->type);
1669 return mono_class_get_flags (klass);
1672 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1673 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1676 MonoClass *klass = field->field->parent;
1677 MonoMarshalType *info;
1681 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1682 if (mono_class_is_gtd (klass) ||
1683 (gklass && gklass->context.class_inst->is_open))
1686 ftype = mono_field_get_type (field->field);
1687 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1690 info = mono_marshal_load_type_info (klass);
1692 for (i = 0; i < info->num_fields; ++i) {
1693 if (info->fields [i].field == field->field) {
1694 if (!info->fields [i].mspec)
1697 MonoReflectionMarshalAsAttribute* obj;
1698 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1699 if (!mono_error_ok (&error))
1700 mono_error_set_pending_exception (&error);
1709 ICALL_EXPORT MonoReflectionField*
1710 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1713 gboolean found = FALSE;
1719 klass = handle->parent;
1721 klass = mono_class_from_mono_type (type);
1723 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1726 /* The managed code will throw the exception */
1730 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1731 mono_error_set_pending_exception (&error);
1735 ICALL_EXPORT MonoReflectionEvent*
1736 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1744 klass = handle->parent;
1746 klass = mono_class_from_mono_type (type);
1748 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1750 /* Managed code will throw an exception */
1754 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1755 mono_error_set_pending_exception (&error);
1760 ICALL_EXPORT MonoReflectionProperty*
1761 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1769 klass = handle->parent;
1771 klass = mono_class_from_mono_type (type);
1773 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1775 /* Managed code will throw an exception */
1779 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1780 mono_error_set_pending_exception (&error);
1784 ICALL_EXPORT MonoArray*
1785 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1788 MonoType *type = mono_field_get_type_checked (field->field, &error);
1791 if (!mono_error_ok (&error)) {
1792 mono_error_set_pending_exception (&error);
1796 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1797 mono_error_set_pending_exception (&error);
1802 vell_icall_get_method_attributes (MonoMethod *method)
1804 return method->flags;
1808 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1811 MonoReflectionType *rt;
1812 MonoDomain *domain = mono_domain_get ();
1813 MonoMethodSignature* sig;
1815 sig = mono_method_signature_checked (method, &error);
1816 if (!mono_error_ok (&error)) {
1817 mono_error_set_pending_exception (&error);
1821 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1822 if (!mono_error_ok (&error)) {
1823 mono_error_set_pending_exception (&error);
1827 MONO_STRUCT_SETREF (info, parent, rt);
1829 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1830 if (!mono_error_ok (&error)) {
1831 mono_error_set_pending_exception (&error);
1835 MONO_STRUCT_SETREF (info, ret, rt);
1837 info->attrs = method->flags;
1838 info->implattrs = method->iflags;
1839 if (sig->call_convention == MONO_CALL_DEFAULT)
1840 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1842 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1847 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1850 ICALL_EXPORT MonoArray*
1851 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1854 MonoDomain *domain = mono_domain_get ();
1856 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1857 mono_error_set_pending_exception (&error);
1861 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1862 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1865 MonoDomain *domain = mono_domain_get ();
1866 MonoReflectionMarshalAsAttribute* res = NULL;
1867 MonoMarshalSpec **mspecs;
1870 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1871 mono_method_get_marshal_info (method, mspecs);
1874 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1875 if (!mono_error_ok (&error)) {
1876 mono_error_set_pending_exception (&error);
1881 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1883 mono_metadata_free_marshal_spec (mspecs [i]);
1890 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1892 MonoClass *parent = field->field->parent;
1893 mono_class_setup_fields (parent);
1895 return field->field->offset - sizeof (MonoObject);
1898 ICALL_EXPORT MonoReflectionType*
1899 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1902 MonoReflectionType *ret;
1905 parent = declaring? field->field->parent: field->klass;
1907 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1908 mono_error_set_pending_exception (&error);
1914 ICALL_EXPORT MonoObject *
1915 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1918 MonoClass *fklass = field->klass;
1919 MonoClassField *cf = field->field;
1920 MonoDomain *domain = mono_object_domain (field);
1922 if (fklass->image->assembly->ref_only) {
1923 mono_set_pending_exception (mono_get_exception_invalid_operation (
1924 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1928 if (mono_security_core_clr_enabled () &&
1929 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1930 mono_error_set_pending_exception (&error);
1934 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1935 mono_error_set_pending_exception (&error);
1940 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1943 MonoClassField *cf = field->field;
1947 if (field->klass->image->assembly->ref_only) {
1948 mono_set_pending_exception (mono_get_exception_invalid_operation (
1949 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1953 if (mono_security_core_clr_enabled () &&
1954 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1955 mono_error_set_pending_exception (&error);
1959 type = mono_field_get_type_checked (cf, &error);
1960 if (!mono_error_ok (&error)) {
1961 mono_error_set_pending_exception (&error);
1965 v = (gchar *) value;
1967 switch (type->type) {
1970 case MONO_TYPE_BOOLEAN:
1973 case MONO_TYPE_CHAR:
1982 case MONO_TYPE_VALUETYPE:
1985 v += sizeof (MonoObject);
1987 case MONO_TYPE_STRING:
1988 case MONO_TYPE_OBJECT:
1989 case MONO_TYPE_CLASS:
1990 case MONO_TYPE_ARRAY:
1991 case MONO_TYPE_SZARRAY:
1994 case MONO_TYPE_GENERICINST: {
1995 MonoGenericClass *gclass = type->data.generic_class;
1996 g_assert (!gclass->context.class_inst->is_open);
1998 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1999 MonoClass *nklass = mono_class_from_mono_type (type);
2000 MonoObject *nullable;
2003 * Convert the boxed vtype into a Nullable structure.
2004 * This is complicated by the fact that Nullables have
2005 * a variable structure.
2007 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2008 if (!mono_error_ok (&error)) {
2009 mono_error_set_pending_exception (&error);
2013 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2015 v = (gchar *)mono_object_unbox (nullable);
2018 if (gclass->container_class->valuetype && (v != NULL))
2019 v += sizeof (MonoObject);
2023 g_error ("type 0x%x not handled in "
2024 "ves_icall_FieldInfo_SetValueInternal", type->type);
2029 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2030 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2031 if (!is_ok (&error)) {
2032 mono_error_set_pending_exception (&error);
2035 if (!vtable->initialized) {
2036 if (!mono_runtime_class_init_full (vtable, &error)) {
2037 mono_error_set_pending_exception (&error);
2041 mono_field_static_set_value (vtable, cf, v);
2043 mono_field_set_value (obj, cf, v);
2048 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2057 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2058 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2062 if (MONO_TYPE_IS_REFERENCE (f->type))
2063 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2065 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2068 ICALL_EXPORT MonoObject *
2069 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2071 MonoObject *o = NULL;
2072 MonoClassField *field = rfield->field;
2074 MonoDomain *domain = mono_object_domain (rfield);
2076 MonoTypeEnum def_type;
2077 const char *def_value;
2081 mono_class_init (field->parent);
2083 t = mono_field_get_type_checked (field, &error);
2084 if (!mono_error_ok (&error)) {
2085 mono_error_set_pending_exception (&error);
2089 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2090 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2094 if (image_is_dynamic (field->parent->image)) {
2095 MonoClass *klass = field->parent;
2096 int fidx = field - klass->fields;
2097 MonoClassExt *ext = mono_class_get_ext (klass);
2100 g_assert (ext->field_def_values);
2101 def_type = ext->field_def_values [fidx].def_type;
2102 def_value = ext->field_def_values [fidx].data;
2104 if (def_type == MONO_TYPE_END) {
2105 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2109 def_value = mono_class_get_field_default_value (field, &def_type);
2110 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2112 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2117 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2121 case MONO_TYPE_BOOLEAN:
2124 case MONO_TYPE_CHAR:
2132 case MONO_TYPE_R8: {
2135 /* boxed value type */
2136 t = g_new0 (MonoType, 1);
2138 klass = mono_class_from_mono_type (t);
2140 o = mono_object_new_checked (domain, klass, &error);
2141 if (!mono_error_ok (&error)) {
2142 mono_error_set_pending_exception (&error);
2145 v = ((gchar *) o) + sizeof (MonoObject);
2146 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2147 if (mono_error_set_pending_exception (&error))
2151 case MONO_TYPE_STRING:
2152 case MONO_TYPE_CLASS:
2153 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2154 if (mono_error_set_pending_exception (&error))
2158 g_assert_not_reached ();
2164 ICALL_EXPORT MonoReflectionType*
2165 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2168 MonoReflectionType *ret;
2171 type = mono_field_get_type_checked (ref_field->field, &error);
2172 if (!mono_error_ok (&error)) {
2173 mono_error_set_pending_exception (&error);
2177 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2178 if (!mono_error_ok (&error)) {
2179 mono_error_set_pending_exception (&error);
2186 /* From MonoProperty.cs */
2188 PInfo_Attributes = 1,
2189 PInfo_GetMethod = 1 << 1,
2190 PInfo_SetMethod = 1 << 2,
2191 PInfo_ReflectedType = 1 << 3,
2192 PInfo_DeclaringType = 1 << 4,
2197 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2200 MonoReflectionType *rt;
2201 MonoReflectionMethod *rm;
2202 MonoDomain *domain = mono_object_domain (property);
2203 const MonoProperty *pproperty = property->property;
2205 if ((req_info & PInfo_ReflectedType) != 0) {
2206 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2207 if (mono_error_set_pending_exception (&error))
2210 MONO_STRUCT_SETREF (info, parent, rt);
2212 if ((req_info & PInfo_DeclaringType) != 0) {
2213 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2214 if (mono_error_set_pending_exception (&error))
2217 MONO_STRUCT_SETREF (info, declaring_type, rt);
2220 if ((req_info & PInfo_Name) != 0)
2221 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2223 if ((req_info & PInfo_Attributes) != 0)
2224 info->attrs = pproperty->attrs;
2226 if ((req_info & PInfo_GetMethod) != 0) {
2227 if (pproperty->get &&
2228 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2229 pproperty->get->klass == property->klass)) {
2230 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2231 if (mono_error_set_pending_exception (&error))
2237 MONO_STRUCT_SETREF (info, get, rm);
2239 if ((req_info & PInfo_SetMethod) != 0) {
2240 if (pproperty->set &&
2241 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2242 pproperty->set->klass == property->klass)) {
2243 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2244 if (mono_error_set_pending_exception (&error))
2250 MONO_STRUCT_SETREF (info, set, rm);
2253 * There may be other methods defined for properties, though, it seems they are not exposed
2254 * in the reflection API
2259 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2262 MonoReflectionType *rt;
2263 MonoReflectionMethod *rm;
2264 MonoDomain *domain = mono_object_domain (event);
2266 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2267 if (mono_error_set_pending_exception (&error))
2270 MONO_STRUCT_SETREF (info, reflected_type, rt);
2272 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2273 if (mono_error_set_pending_exception (&error))
2276 MONO_STRUCT_SETREF (info, declaring_type, rt);
2278 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2279 info->attrs = event->event->attrs;
2281 if (event->event->add) {
2282 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2283 if (mono_error_set_pending_exception (&error))
2289 MONO_STRUCT_SETREF (info, add_method, rm);
2291 if (event->event->remove) {
2292 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2293 if (mono_error_set_pending_exception (&error))
2299 MONO_STRUCT_SETREF (info, remove_method, rm);
2301 if (event->event->raise) {
2302 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2303 if (mono_error_set_pending_exception (&error))
2309 MONO_STRUCT_SETREF (info, raise_method, rm);
2311 #ifndef MONO_SMALL_CONFIG
2312 if (event->event->other) {
2314 while (event->event->other [n])
2316 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2317 if (mono_error_set_pending_exception (&error))
2319 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2321 for (i = 0; i < n; i++) {
2322 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2323 if (mono_error_set_pending_exception (&error))
2325 mono_array_setref (info->other_methods, i, rm);
2332 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2337 mono_class_setup_interfaces (klass, error);
2338 if (!mono_error_ok (error))
2341 for (i = 0; i < klass->interface_count; i++) {
2342 ic = klass->interfaces [i];
2343 g_hash_table_insert (ifaces, ic, ic);
2345 collect_interfaces (ic, ifaces, error);
2346 if (!mono_error_ok (error))
2352 MonoArray *iface_array;
2353 MonoGenericContext *context;
2357 } FillIfaceArrayData;
2360 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2362 MonoReflectionType *rt;
2363 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2364 MonoClass *ic = (MonoClass *)key;
2365 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2367 if (!mono_error_ok (data->error))
2370 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2371 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2372 if (!mono_error_ok (data->error))
2376 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2377 if (!mono_error_ok (data->error))
2380 mono_array_setref (data->iface_array, data->next_idx++, rt);
2383 mono_metadata_free_type (inflated);
2387 get_interfaces_hash (gconstpointer v1)
2389 MonoClass *k = (MonoClass*)v1;
2391 return k->type_token;
2394 ICALL_EXPORT MonoArray*
2395 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2398 MonoClass *klass = mono_class_from_mono_type (type->type);
2400 FillIfaceArrayData data = { 0 };
2403 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2405 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2406 data.context = mono_class_get_context (klass);
2407 klass = mono_class_get_generic_class (klass)->container_class;
2410 for (parent = klass; parent; parent = parent->parent) {
2411 mono_class_setup_interfaces (parent, &error);
2412 if (!mono_error_ok (&error))
2414 collect_interfaces (parent, iface_hash, &error);
2415 if (!mono_error_ok (&error))
2419 data.error = &error;
2420 data.domain = mono_object_domain (type);
2422 len = g_hash_table_size (iface_hash);
2424 g_hash_table_destroy (iface_hash);
2425 if (!data.domain->empty_types) {
2426 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2427 if (!is_ok (&error))
2430 return data.domain->empty_types;
2433 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2434 if (!is_ok (&error))
2436 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2437 if (!mono_error_ok (&error))
2440 g_hash_table_destroy (iface_hash);
2441 return data.iface_array;
2444 g_hash_table_destroy (iface_hash);
2445 mono_error_set_pending_exception (&error);
2450 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2452 gboolean variance_used;
2453 MonoClass *klass = mono_class_from_mono_type (type->type);
2454 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2455 MonoReflectionMethod *member;
2458 int i = 0, len, ioffset;
2462 mono_class_init_checked (klass, &error);
2463 if (mono_error_set_pending_exception (&error))
2465 mono_class_init_checked (iclass, &error);
2466 if (mono_error_set_pending_exception (&error))
2469 mono_class_setup_vtable (klass);
2471 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2475 len = mono_class_num_methods (iclass);
2476 domain = mono_object_domain (type);
2477 MonoArray *targets_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 (targets, (MonoObject*) targets_arr);
2481 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2482 if (mono_error_set_pending_exception (&error))
2484 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2486 while ((method = mono_class_get_methods (iclass, &iter))) {
2487 member = mono_method_get_object_checked (domain, method, iclass, &error);
2488 if (mono_error_set_pending_exception (&error))
2490 mono_array_setref (*methods, i, member);
2491 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2492 if (mono_error_set_pending_exception (&error))
2494 mono_array_setref (*targets, i, member);
2501 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2504 MonoClass *klass = mono_class_from_mono_type (type->type);
2506 mono_class_init_checked (klass, &error);
2507 if (mono_error_set_pending_exception (&error))
2510 if (image_is_dynamic (klass->image)) {
2511 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2512 *packing = tb->packing_size;
2513 *size = tb->class_size;
2515 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2519 ICALL_EXPORT MonoReflectionType*
2520 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2523 MonoReflectionType *ret;
2526 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2527 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2528 mono_error_set_pending_exception (&error);
2532 klass = mono_class_from_mono_type (type->type);
2533 mono_class_init_checked (klass, &error);
2534 if (mono_error_set_pending_exception (&error))
2538 // GetElementType should only return a type for:
2539 // Array Pointer PassedByRef
2540 if (type->type->byref)
2541 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2542 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2543 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2544 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2545 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2549 mono_error_set_pending_exception (&error);
2554 ICALL_EXPORT MonoReflectionType*
2555 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2558 MonoReflectionType *ret;
2560 if (type->type->byref)
2563 MonoClass *klass = mono_class_from_mono_type (type->type);
2567 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2568 mono_error_set_pending_exception (&error);
2573 ICALL_EXPORT MonoBoolean
2574 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2576 return type->type->type == MONO_TYPE_PTR;
2579 ICALL_EXPORT MonoBoolean
2580 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2582 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)));
2585 ICALL_EXPORT MonoBoolean
2586 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2588 return type->type->byref;
2591 ICALL_EXPORT MonoBoolean
2592 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2595 MonoClass *klass = mono_class_from_mono_type (type->type);
2596 mono_class_init_checked (klass, &error);
2597 if (mono_error_set_pending_exception (&error))
2600 return mono_class_is_com_object (klass);
2603 ICALL_EXPORT guint32
2604 ves_icall_reflection_get_token (MonoObject* obj)
2607 guint32 result = mono_reflection_get_token_checked (obj, &error);
2608 mono_error_set_pending_exception (&error);
2612 ICALL_EXPORT MonoReflectionModule*
2613 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2616 MonoReflectionModule *result = NULL;
2617 MonoClass *klass = mono_class_from_mono_type (type->type);
2618 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2619 mono_error_set_pending_exception (&error);
2623 ICALL_EXPORT MonoReflectionAssembly*
2624 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2627 MonoDomain *domain = mono_domain_get ();
2628 MonoClass *klass = mono_class_from_mono_type (type->type);
2629 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2630 mono_error_set_pending_exception (&error);
2634 ICALL_EXPORT MonoReflectionType*
2635 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2638 MonoReflectionType *ret;
2639 MonoDomain *domain = mono_domain_get ();
2642 if (type->type->byref)
2644 if (type->type->type == MONO_TYPE_VAR) {
2645 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2646 klass = param ? param->owner.klass : NULL;
2647 } else if (type->type->type == MONO_TYPE_MVAR) {
2648 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2649 klass = param ? param->owner.method->klass : NULL;
2651 klass = mono_class_from_mono_type (type->type)->nested_in;
2657 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2658 mono_error_set_pending_exception (&error);
2663 ICALL_EXPORT MonoStringHandle
2664 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2666 MonoDomain *domain = mono_domain_get ();
2667 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2668 MonoClass *klass = mono_class_from_mono_type (type);
2671 char *n = g_strdup_printf ("%s&", klass->name);
2672 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2678 return mono_string_new_handle (domain, klass->name, error);
2682 ICALL_EXPORT MonoStringHandle
2683 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2685 MonoDomain *domain = mono_domain_get ();
2686 MonoClass *klass = mono_class_from_mono_type_handle (type);
2688 while (klass->nested_in)
2689 klass = klass->nested_in;
2691 if (klass->name_space [0] == '\0')
2692 return NULL_HANDLE_STRING;
2694 return mono_string_new_handle (domain, klass->name_space, error);
2698 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2702 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2703 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2707 klass = mono_class_from_mono_type (type->type);
2713 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2715 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2718 ICALL_EXPORT MonoArray*
2719 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2722 MonoReflectionType *rt;
2724 MonoClass *klass, *pklass;
2725 MonoDomain *domain = mono_object_domain (type);
2728 klass = mono_class_from_mono_type (type->type);
2730 if (mono_class_is_gtd (klass)) {
2731 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2732 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2733 if (mono_error_set_pending_exception (&error))
2735 for (i = 0; i < container->type_argc; ++i) {
2736 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2738 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2739 if (mono_error_set_pending_exception (&error))
2742 mono_array_setref (res, i, rt);
2744 } else if (mono_class_is_ginst (klass)) {
2745 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2746 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2747 if (mono_error_set_pending_exception (&error))
2749 for (i = 0; i < inst->type_argc; ++i) {
2750 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2751 if (mono_error_set_pending_exception (&error))
2754 mono_array_setref (res, i, rt);
2762 ICALL_EXPORT gboolean
2763 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2767 if (!IS_MONOTYPE (type))
2770 if (type->type->byref)
2773 klass = mono_class_from_mono_type (type->type);
2774 return mono_class_is_gtd (klass);
2777 ICALL_EXPORT MonoReflectionType*
2778 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2781 MonoReflectionType *ret;
2784 if (type->type->byref)
2787 klass = mono_class_from_mono_type (type->type);
2789 if (mono_class_is_gtd (klass)) {
2790 return type; /* check this one */
2792 if (mono_class_is_ginst (klass)) {
2793 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2796 tb = mono_class_get_ref_info (generic_class);
2798 if (generic_class->wastypebuilder && tb)
2799 return (MonoReflectionType *)tb;
2801 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2802 mono_error_set_pending_exception (&error);
2810 ICALL_EXPORT MonoReflectionType*
2811 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2814 MonoReflectionType *ret;
2816 MonoType *geninst, **types;
2819 g_assert (IS_MONOTYPE (type));
2820 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2821 if (mono_error_set_pending_exception (&error))
2824 count = mono_array_length (type_array);
2825 types = g_new0 (MonoType *, count);
2827 for (i = 0; i < count; i++) {
2828 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2829 types [i] = t->type;
2832 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2835 mono_error_set_pending_exception (&error);
2839 klass = mono_class_from_mono_type (geninst);
2841 /*we might inflate to the GTD*/
2842 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2843 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2847 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2848 mono_error_set_pending_exception (&error);
2853 ICALL_EXPORT gboolean
2854 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2858 if (!IS_MONOTYPE (type))
2861 if (type->type->byref)
2864 klass = mono_class_from_mono_type (type->type);
2865 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2869 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2871 if (!IS_MONOTYPE (type))
2874 if (is_generic_parameter (type->type))
2875 return mono_type_get_generic_param_num (type->type);
2879 ICALL_EXPORT MonoGenericParamInfo *
2880 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2882 return mono_generic_param_info (type->type->data.generic_param);
2885 ICALL_EXPORT MonoBoolean
2886 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2888 return is_generic_parameter (type->type);
2891 ICALL_EXPORT MonoReflectionMethod*
2892 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2893 MonoReflectionMethod* generic)
2900 MonoReflectionMethod *ret = NULL;
2902 domain = ((MonoObject *)type)->vtable->domain;
2904 klass = mono_class_from_mono_type (type->type);
2905 mono_class_init_checked (klass, &error);
2906 if (mono_error_set_pending_exception (&error))
2910 while ((method = mono_class_get_methods (klass, &iter))) {
2911 if (method->token == generic->method->token) {
2912 ret = mono_method_get_object_checked (domain, method, klass, &error);
2913 if (mono_error_set_pending_exception (&error))
2921 ICALL_EXPORT MonoReflectionMethod *
2922 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2925 MonoType *type = ref_type->type;
2927 MonoReflectionMethod *ret = NULL;
2929 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2930 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2933 if (type->type == MONO_TYPE_VAR)
2936 method = mono_type_get_generic_param_owner (type)->owner.method;
2939 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2940 if (!mono_error_ok (&error))
2941 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2945 ICALL_EXPORT MonoBoolean
2946 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2948 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2952 ICALL_EXPORT MonoBoolean
2953 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2955 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2960 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2962 MonoDomain *domain = mono_domain_get ();
2963 MonoImage *image = method->method->klass->image;
2964 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2965 MonoTableInfo *tables = image->tables;
2966 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2967 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2968 guint32 im_cols [MONO_IMPLMAP_SIZE];
2969 guint32 scope_token;
2970 const char *import = NULL;
2971 const char *scope = NULL;
2973 if (image_is_dynamic (image)) {
2974 MonoReflectionMethodAux *method_aux =
2975 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2977 import = method_aux->dllentry;
2978 scope = method_aux->dll;
2981 if (!import || !scope) {
2982 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2987 if (piinfo->implmap_idx) {
2988 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2990 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2991 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2992 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2993 scope = mono_metadata_string_heap (image, scope_token);
2997 *flags = piinfo->piflags;
2998 *entry_point = mono_string_new (domain, import);
2999 *dll_name = mono_string_new (domain, scope);
3002 ICALL_EXPORT MonoReflectionMethod *
3003 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3005 MonoMethodInflated *imethod;
3007 MonoReflectionMethod *ret = NULL;
3010 if (method->method->is_generic)
3013 if (!method->method->is_inflated)
3016 imethod = (MonoMethodInflated *) method->method;
3018 result = imethod->declaring;
3019 /* Not a generic method. */
3020 if (!result->is_generic)
3023 if (image_is_dynamic (method->method->klass->image)) {
3024 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3025 MonoReflectionMethod *res;
3028 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3029 * the dynamic case as well ?
3031 mono_image_lock ((MonoImage*)image);
3032 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3033 mono_image_unlock ((MonoImage*)image);
3039 if (imethod->context.class_inst) {
3040 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3041 /*Generic methods gets the context of the GTD.*/
3042 if (mono_class_get_context (klass)) {
3043 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3044 if (!mono_error_ok (&error))
3049 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3051 if (!mono_error_ok (&error))
3052 mono_error_set_pending_exception (&error);
3056 ICALL_EXPORT gboolean
3057 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3059 return mono_method_signature (method->method)->generic_param_count != 0;
3062 ICALL_EXPORT gboolean
3063 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3065 return method->method->is_generic;
3068 ICALL_EXPORT MonoArray*
3069 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3072 MonoReflectionType *rt;
3077 domain = mono_object_domain (method);
3079 if (method->method->is_inflated) {
3080 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3083 count = inst->type_argc;
3084 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3085 if (mono_error_set_pending_exception (&error))
3088 for (i = 0; i < count; i++) {
3089 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3090 if (mono_error_set_pending_exception (&error))
3093 mono_array_setref (res, i, rt);
3100 count = mono_method_signature (method->method)->generic_param_count;
3101 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3102 if (mono_error_set_pending_exception (&error))
3105 for (i = 0; i < count; i++) {
3106 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3107 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3108 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3110 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3111 if (mono_error_set_pending_exception (&error))
3114 mono_array_setref (res, i, rt);
3120 ICALL_EXPORT MonoObject *
3121 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3125 * Invoke from reflection is supposed to always be a virtual call (the API
3126 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3127 * greater flexibility.
3129 MonoMethod *m = method->method;
3130 MonoMethodSignature *sig = mono_method_signature (m);
3133 void *obj = this_arg;
3137 if (mono_security_core_clr_enabled () &&
3138 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3139 mono_error_set_pending_exception (&error);
3143 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3144 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3145 mono_error_cleanup (&error); /* FIXME does this make sense? */
3146 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3151 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3152 if (!is_ok (&error)) {
3153 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3156 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3157 char *target_name = mono_type_get_full_name (m->klass);
3158 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3159 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3161 g_free (target_name);
3165 m = mono_object_get_virtual_method (this_arg, m);
3166 /* must pass the pointer to the value for valuetype methods */
3167 if (m->klass->valuetype)
3168 obj = mono_object_unbox (this_arg);
3169 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3170 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3175 if (sig->ret->byref) {
3176 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"));
3180 pcount = params? mono_array_length (params): 0;
3181 if (pcount != sig->param_count) {
3182 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3186 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3187 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."));
3191 image = m->klass->image;
3192 if (image->assembly->ref_only) {
3193 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."));
3197 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3198 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3202 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3206 intptr_t *lower_bounds;
3207 pcount = mono_array_length (params);
3208 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3209 /* Note: the synthetized array .ctors have int32 as argument type */
3210 for (i = 0; i < pcount; ++i)
3211 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3213 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3214 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3215 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3216 if (!mono_error_ok (&error)) {
3217 mono_error_set_pending_exception (&error);
3221 for (i = 0; i < mono_array_length (arr); ++i) {
3222 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3223 if (!mono_error_ok (&error)) {
3224 mono_error_set_pending_exception (&error);
3227 mono_array_setref_fast (arr, i, subarray);
3229 return (MonoObject*)arr;
3232 if (m->klass->rank == pcount) {
3233 /* Only lengths provided. */
3234 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3235 if (!mono_error_ok (&error)) {
3236 mono_error_set_pending_exception (&error);
3240 return (MonoObject*)arr;
3242 g_assert (pcount == (m->klass->rank * 2));
3243 /* The arguments are lower-bound-length pairs */
3244 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3246 for (i = 0; i < pcount / 2; ++i) {
3247 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3248 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3251 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3252 if (!mono_error_ok (&error)) {
3253 mono_error_set_pending_exception (&error);
3257 return (MonoObject*)arr;
3260 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3261 mono_error_set_pending_exception (&error);
3265 #ifndef DISABLE_REMOTING
3266 ICALL_EXPORT MonoObject *
3267 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3270 MonoDomain *domain = mono_object_domain (method);
3271 MonoMethod *m = method->method;
3272 MonoMethodSignature *sig = mono_method_signature (m);
3273 MonoArray *out_args;
3275 int i, j, outarg_count = 0;
3277 if (m->klass == mono_defaults.object_class) {
3278 if (!strcmp (m->name, "FieldGetter")) {
3279 MonoClass *k = this_arg->vtable->klass;
3283 /* If this is a proxy, then it must be a CBO */
3284 if (k == mono_defaults.transparent_proxy_class) {
3285 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3286 this_arg = tp->rp->unwrapped_server;
3287 g_assert (this_arg);
3288 k = this_arg->vtable->klass;
3291 name = mono_array_get (params, MonoString *, 1);
3292 str = mono_string_to_utf8_checked (name, &error);
3293 if (mono_error_set_pending_exception (&error))
3297 MonoClassField* field = mono_class_get_field_from_name (k, str);
3300 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3301 if (field_klass->valuetype) {
3302 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3303 if (mono_error_set_pending_exception (&error))
3306 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3308 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3309 if (mono_error_set_pending_exception (&error))
3311 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3312 mono_array_setref (out_args, 0, result);
3319 g_assert_not_reached ();
3321 } else if (!strcmp (m->name, "FieldSetter")) {
3322 MonoClass *k = this_arg->vtable->klass;
3328 /* If this is a proxy, then it must be a CBO */
3329 if (k == mono_defaults.transparent_proxy_class) {
3330 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3331 this_arg = tp->rp->unwrapped_server;
3332 g_assert (this_arg);
3333 k = this_arg->vtable->klass;
3336 name = mono_array_get (params, MonoString *, 1);
3337 str = mono_string_to_utf8_checked (name, &error);
3338 if (mono_error_set_pending_exception (&error))
3342 MonoClassField* field = mono_class_get_field_from_name (k, str);
3345 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3346 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3348 if (field_klass->valuetype) {
3349 size = mono_type_size (field->type, &align);
3350 g_assert (size == mono_class_value_size (field_klass, NULL));
3351 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3353 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3356 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3357 if (mono_error_set_pending_exception (&error))
3359 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3368 g_assert_not_reached ();
3373 for (i = 0; i < mono_array_length (params); i++) {
3374 if (sig->params [i]->byref)
3378 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3379 if (mono_error_set_pending_exception (&error))
3382 /* handle constructors only for objects already allocated */
3383 if (!strcmp (method->method->name, ".ctor"))
3384 g_assert (this_arg);
3386 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3387 g_assert (!method->method->klass->valuetype);
3388 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3389 if (mono_error_set_pending_exception (&error))
3392 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3393 if (sig->params [i]->byref) {
3395 arg = mono_array_get (params, gpointer, i);
3396 mono_array_setref (out_args, j, arg);
3401 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3408 read_enum_value (const char *mem, int type)
3411 case MONO_TYPE_BOOLEAN:
3413 return *(guint8*)mem;
3415 return *(gint8*)mem;
3416 case MONO_TYPE_CHAR:
3418 return read16 (mem);
3420 return (gint16) read16 (mem);
3422 return read32 (mem);
3424 return (gint32) read32 (mem);
3427 return read64 (mem);
3429 g_assert_not_reached ();
3435 write_enum_value (char *mem, int type, guint64 value)
3439 case MONO_TYPE_I1: {
3440 guint8 *p = (guint8*)mem;
3446 case MONO_TYPE_CHAR: {
3447 guint16 *p = (guint16 *)mem;
3452 case MONO_TYPE_I4: {
3453 guint32 *p = (guint32 *)mem;
3458 case MONO_TYPE_I8: {
3459 guint64 *p = (guint64 *)mem;
3464 g_assert_not_reached ();
3469 ICALL_EXPORT MonoObject *
3470 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3478 domain = mono_object_domain (enumType);
3479 enumc = mono_class_from_mono_type (enumType->type);
3481 mono_class_init_checked (enumc, &error);
3482 if (mono_error_set_pending_exception (&error))
3485 etype = mono_class_enum_basetype (enumc);
3487 res = mono_object_new_checked (domain, enumc, &error);
3488 if (mono_error_set_pending_exception (&error))
3490 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3495 ICALL_EXPORT MonoBoolean
3496 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3498 int size = mono_class_value_size (a->vtable->klass, NULL);
3499 guint64 a_val = 0, b_val = 0;
3501 memcpy (&a_val, mono_object_unbox (a), size);
3502 memcpy (&b_val, mono_object_unbox (b), size);
3504 return (a_val & b_val) == b_val;
3507 ICALL_EXPORT MonoObject *
3508 ves_icall_System_Enum_get_value (MonoObject *eobj)
3520 g_assert (eobj->vtable->klass->enumtype);
3522 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3523 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3524 if (mono_error_set_pending_exception (&error))
3526 dst = (char *)res + sizeof (MonoObject);
3527 src = (char *)eobj + sizeof (MonoObject);
3528 size = mono_class_value_size (enumc, NULL);
3530 memcpy (dst, src, size);
3535 ICALL_EXPORT MonoReflectionType *
3536 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3539 MonoReflectionType *ret;
3543 klass = mono_class_from_mono_type (type->type);
3544 mono_class_init_checked (klass, &error);
3545 if (mono_error_set_pending_exception (&error))
3548 etype = mono_class_enum_basetype (klass);
3550 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3554 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3555 mono_error_set_pending_exception (&error);
3561 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3563 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3564 gpointer odata = (char *)other + sizeof (MonoObject);
3565 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3566 g_assert (basetype);
3571 if (eobj->vtable->klass != other->vtable->klass)
3574 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3575 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3576 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3579 return me > other ? 1 : -1; \
3582 switch (basetype->type) {
3584 COMPARE_ENUM_VALUES (guint8);
3586 COMPARE_ENUM_VALUES (gint8);
3587 case MONO_TYPE_CHAR:
3589 COMPARE_ENUM_VALUES (guint16);
3591 COMPARE_ENUM_VALUES (gint16);
3593 COMPARE_ENUM_VALUES (guint32);
3595 COMPARE_ENUM_VALUES (gint32);
3597 COMPARE_ENUM_VALUES (guint64);
3599 COMPARE_ENUM_VALUES (gint64);
3603 #undef COMPARE_ENUM_VALUES
3604 /* indicates that the enum was of an unsupported unerlying type */
3609 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3611 gpointer data = (char *)eobj + sizeof (MonoObject);
3612 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3613 g_assert (basetype);
3615 switch (basetype->type) {
3616 case MONO_TYPE_I1: {
3617 gint8 value = *((gint8*)data);
3618 return ((int)value ^ (int)value << 8);
3621 return *((guint8*)data);
3622 case MONO_TYPE_CHAR:
3624 return *((guint16*)data);
3626 case MONO_TYPE_I2: {
3627 gint16 value = *((gint16*)data);
3628 return ((int)(guint16)value | (((int)value) << 16));
3631 return *((guint32*)data);
3633 return *((gint32*)data);
3635 case MONO_TYPE_I8: {
3636 gint64 value = *((gint64*)data);
3637 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3640 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3646 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3648 mono_error_init (error);
3649 HANDLE_FUNCTION_ENTER();
3650 guint64 field_value;
3652 MonoTypeEnum def_type;
3654 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3656 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3658 if (mono_field_is_deleted (field))
3660 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3663 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3665 p = mono_class_get_field_default_value (field, &def_type);
3666 /* len = */ mono_metadata_decode_blob_size (p, &p);
3668 field_value = read_enum_value (p, base_type);
3669 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3671 if (*previous_value > field_value)
3674 *previous_value = field_value;
3677 HANDLE_FUNCTION_RETURN();
3680 ICALL_EXPORT MonoBoolean
3681 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3683 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3684 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3685 guint j = 0, nvalues;
3687 MonoClassField *field;
3689 guint64 previous_value = 0;
3690 gboolean sorted = TRUE;
3692 mono_error_init (error);
3693 mono_class_init_checked (enumc, error);
3694 return_val_if_nok (error, FALSE);
3696 if (!enumc->enumtype) {
3697 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3701 base_type = mono_class_enum_basetype (enumc)->type;
3703 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3704 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3705 return_val_if_nok (error, FALSE);
3706 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3707 return_val_if_nok (error, FALSE);
3710 while ((field = mono_class_get_fields (enumc, &iter))) {
3711 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3715 return_val_if_nok (error, FALSE);
3721 BFLAGS_IgnoreCase = 1,
3722 BFLAGS_DeclaredOnly = 2,
3723 BFLAGS_Instance = 4,
3725 BFLAGS_Public = 0x10,
3726 BFLAGS_NonPublic = 0x20,
3727 BFLAGS_FlattenHierarchy = 0x40,
3728 BFLAGS_InvokeMethod = 0x100,
3729 BFLAGS_CreateInstance = 0x200,
3730 BFLAGS_GetField = 0x400,
3731 BFLAGS_SetField = 0x800,
3732 BFLAGS_GetProperty = 0x1000,
3733 BFLAGS_SetProperty = 0x2000,
3734 BFLAGS_ExactBinding = 0x10000,
3735 BFLAGS_SuppressChangeType = 0x20000,
3736 BFLAGS_OptionalParamBinding = 0x40000
3739 ICALL_EXPORT GPtrArray*
3740 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3743 MonoClass *startklass, *klass;
3746 int (*compare_func) (const char *s1, const char *s2) = NULL;
3747 MonoClassField *field;
3749 if (type->type->byref) {
3750 return g_ptr_array_new ();
3753 mono_error_init (&error);
3755 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3757 klass = startklass = mono_class_from_mono_type (type->type);
3759 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3762 if (mono_class_has_failure (klass)) {
3763 mono_error_set_for_class_failure (&error, klass);
3768 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3769 guint32 flags = mono_field_get_flags (field);
3771 if (mono_field_is_deleted_with_flags (field, flags))
3773 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3774 if (bflags & BFLAGS_Public)
3776 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3777 if (bflags & BFLAGS_NonPublic) {
3784 if (flags & FIELD_ATTRIBUTE_STATIC) {
3785 if (bflags & BFLAGS_Static)
3786 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3789 if (bflags & BFLAGS_Instance)
3796 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3799 g_ptr_array_add (ptr_array, field);
3801 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3807 g_ptr_array_free (ptr_array, TRUE);
3808 mono_error_set_pending_exception (&error);
3813 method_nonpublic (MonoMethod* method, gboolean start_klass)
3815 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3816 case METHOD_ATTRIBUTE_ASSEM:
3817 return (start_klass || mono_defaults.generic_ilist_class);
3818 case METHOD_ATTRIBUTE_PRIVATE:
3820 case METHOD_ATTRIBUTE_PUBLIC:
3828 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3831 MonoClass *startklass;
3835 /*FIXME, use MonoBitSet*/
3836 guint32 method_slots_default [8];
3837 guint32 *method_slots = NULL;
3838 int (*compare_func) (const char *s1, const char *s2) = NULL;
3840 array = g_ptr_array_new ();
3842 mono_error_init (error);
3845 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3847 /* An optimization for calls made from Delegate:CreateDelegate () */
3848 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3849 method = mono_get_delegate_invoke (klass);
3852 g_ptr_array_add (array, method);
3856 mono_class_setup_methods (klass);
3857 mono_class_setup_vtable (klass);
3858 if (mono_class_has_failure (klass))
3861 if (is_generic_parameter (&klass->byval_arg))
3862 nslots = mono_class_get_vtable_size (klass->parent);
3864 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3865 if (nslots >= sizeof (method_slots_default) * 8) {
3866 method_slots = g_new0 (guint32, nslots / 32 + 1);
3868 method_slots = method_slots_default;
3869 memset (method_slots, 0, sizeof (method_slots_default));
3872 mono_class_setup_methods (klass);
3873 mono_class_setup_vtable (klass);
3874 if (mono_class_has_failure (klass))
3878 while ((method = mono_class_get_methods (klass, &iter))) {
3880 if (method->slot != -1) {
3881 g_assert (method->slot < nslots);
3882 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3884 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3885 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3888 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3890 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3891 if (bflags & BFLAGS_Public)
3893 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3899 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3900 if (bflags & BFLAGS_Static)
3901 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3904 if (bflags & BFLAGS_Instance)
3912 if (compare_func (name, method->name))
3917 g_ptr_array_add (array, method);
3919 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3921 if (method_slots != method_slots_default)
3922 g_free (method_slots);
3927 if (method_slots != method_slots_default)
3928 g_free (method_slots);
3929 g_ptr_array_free (array, TRUE);
3931 g_assert (mono_class_has_failure (klass));
3932 mono_error_set_for_class_failure (error, klass);
3936 ICALL_EXPORT GPtrArray*
3937 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3940 GPtrArray *method_array;
3943 klass = mono_class_from_mono_type (type->type);
3944 if (type->type->byref) {
3945 return g_ptr_array_new ();
3948 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3949 mono_error_set_pending_exception (&error);
3950 return method_array;
3953 ICALL_EXPORT GPtrArray*
3954 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3956 MonoClass *startklass, *klass;
3959 gpointer iter = NULL;
3960 GPtrArray *res_array;
3963 if (type->type->byref) {
3964 return g_ptr_array_new ();
3967 klass = startklass = mono_class_from_mono_type (type->type);
3969 mono_class_setup_methods (klass);
3970 if (mono_class_has_failure (klass)) {
3971 mono_error_init (&error);
3972 mono_error_set_for_class_failure (&error, klass);
3973 mono_error_set_pending_exception (&error);
3977 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3980 while ((method = mono_class_get_methods (klass, &iter))) {
3982 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3984 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3985 if (bflags & BFLAGS_Public)
3988 if (bflags & BFLAGS_NonPublic)
3994 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3995 if (bflags & BFLAGS_Static)
3996 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3999 if (bflags & BFLAGS_Instance)
4005 g_ptr_array_add (res_array, method);
4012 property_hash (gconstpointer data)
4014 MonoProperty *prop = (MonoProperty*)data;
4016 return g_str_hash (prop->name);
4020 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4022 if (method1->slot != -1 && method1->slot == method2->slot)
4025 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4026 if (method1->is_inflated)
4027 method1 = ((MonoMethodInflated*) method1)->declaring;
4028 if (method2->is_inflated)
4029 method2 = ((MonoMethodInflated*) method2)->declaring;
4032 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4036 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4038 // Properties are hide-by-name-and-signature
4039 if (!g_str_equal (prop1->name, prop2->name))
4042 /* If we see a property in a generic method, we want to
4043 compare the generic signatures, not the inflated signatures
4044 because we might conflate two properties that were
4048 public T this[T t] { getter { return t; } } // method 1
4049 public U this[U u] { getter { return u; } } // method 2
4052 If we see int Foo<int,int>::Item[int] we need to know if
4053 the indexer came from method 1 or from method 2, and we
4054 shouldn't conflate them. (Bugzilla 36283)
4056 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4059 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4066 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4071 return method_nonpublic (accessor, start_klass);
4074 ICALL_EXPORT GPtrArray*
4075 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4078 MonoClass *startklass, *klass;
4083 int (*compare_func) (const char *s1, const char *s2) = NULL;
4085 GHashTable *properties = NULL;
4086 GPtrArray *res_array;
4088 if (type->type->byref) {
4089 return g_ptr_array_new ();
4092 mono_error_init (&error);
4094 klass = startklass = mono_class_from_mono_type (type->type);
4096 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4098 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4100 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4102 mono_class_setup_methods (klass);
4103 mono_class_setup_vtable (klass);
4104 if (mono_class_has_failure (klass)) {
4105 mono_error_set_for_class_failure (&error, klass);
4110 while ((prop = mono_class_get_properties (klass, &iter))) {
4116 flags = method->flags;
4119 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4120 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4121 if (bflags & BFLAGS_Public)
4123 } else if (bflags & BFLAGS_NonPublic) {
4124 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4125 property_accessor_nonpublic(prop->set, startklass == klass)) {
4132 if (flags & METHOD_ATTRIBUTE_STATIC) {
4133 if (bflags & BFLAGS_Static)
4134 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4137 if (bflags & BFLAGS_Instance)
4145 if (propname != NULL && compare_func (propname, prop->name))
4148 if (g_hash_table_lookup (properties, prop))
4151 g_ptr_array_add (res_array, prop);
4153 g_hash_table_insert (properties, prop, prop);
4155 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4158 g_hash_table_destroy (properties);
4165 g_hash_table_destroy (properties);
4166 g_ptr_array_free (res_array, TRUE);
4168 mono_error_set_pending_exception (&error);
4174 event_hash (gconstpointer data)
4176 MonoEvent *event = (MonoEvent*)data;
4178 return g_str_hash (event->name);
4182 event_equal (MonoEvent *event1, MonoEvent *event2)
4184 // Events are hide-by-name
4185 return g_str_equal (event1->name, event2->name);
4188 ICALL_EXPORT GPtrArray*
4189 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4192 MonoClass *startklass, *klass;
4197 int (*compare_func) (const char *s1, const char *s2) = NULL;
4198 GHashTable *events = NULL;
4199 GPtrArray *res_array;
4201 if (type->type->byref) {
4202 return g_ptr_array_new ();
4205 mono_error_init (&error);
4207 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4209 res_array = g_ptr_array_sized_new (4);
4211 klass = startklass = mono_class_from_mono_type (type->type);
4213 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4215 mono_class_setup_methods (klass);
4216 mono_class_setup_vtable (klass);
4217 if (mono_class_has_failure (klass)) {
4218 mono_error_set_for_class_failure (&error, klass);
4223 while ((event = mono_class_get_events (klass, &iter))) {
4225 method = event->add;
4227 method = event->remove;
4229 method = event->raise;
4231 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4232 if (bflags & BFLAGS_Public)
4234 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4235 if (bflags & BFLAGS_NonPublic)
4240 if (bflags & BFLAGS_NonPublic)
4246 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4247 if (bflags & BFLAGS_Static)
4248 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4251 if (bflags & BFLAGS_Instance)
4256 if (bflags & BFLAGS_Instance)
4261 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4264 if (g_hash_table_lookup (events, event))
4267 g_ptr_array_add (res_array, event);
4269 g_hash_table_insert (events, event, event);
4271 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4274 g_hash_table_destroy (events);
4280 g_hash_table_destroy (events);
4282 g_ptr_array_free (res_array, TRUE);
4284 mono_error_set_pending_exception (&error);
4288 ICALL_EXPORT GPtrArray *
4289 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4295 GPtrArray *res_array;
4297 if (type->type->byref) {
4298 return g_ptr_array_new ();
4301 klass = mono_class_from_mono_type (type->type);
4304 * If a nested type is generic, return its generic type definition.
4305 * Note that this means that the return value is essentially the set
4306 * of nested types of the generic type definition of @klass.
4308 * A note in MSDN claims that a generic type definition can have
4309 * nested types that aren't generic. In any case, the container of that
4310 * nested type would be the generic type definition.
4312 if (mono_class_is_ginst (klass))
4313 klass = mono_class_get_generic_class (klass)->container_class;
4315 res_array = g_ptr_array_new ();
4318 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4320 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4321 if (bflags & BFLAGS_Public)
4324 if (bflags & BFLAGS_NonPublic)
4330 if (str != NULL && strcmp (nested->name, str))
4333 g_ptr_array_add (res_array, &nested->byval_arg);
4339 ICALL_EXPORT MonoReflectionType*
4340 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4343 MonoReflectionType *ret;
4345 MonoType *type = NULL;
4346 MonoTypeNameParse info;
4347 gboolean type_resolve;
4349 /* On MS.NET, this does not fire a TypeResolve event */
4350 type_resolve = TRUE;
4351 str = mono_string_to_utf8_checked (name, &error);
4352 if (mono_error_set_pending_exception (&error))
4354 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4355 if (!mono_reflection_parse_type (str, &info)) {
4357 mono_reflection_free_type_info (&info);
4359 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4362 /*g_print ("failed parse\n");*/
4366 if (info.assembly.name) {
4368 mono_reflection_free_type_info (&info);
4370 /* 1.0 and 2.0 throw different exceptions */
4371 if (mono_defaults.generic_ilist_class)
4372 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4374 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4380 if (module != NULL) {
4381 if (module->image) {
4382 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4383 if (!is_ok (&error)) {
4385 mono_reflection_free_type_info (&info);
4386 mono_error_set_pending_exception (&error);
4393 if (assembly_is_dynamic (assembly->assembly)) {
4394 /* Enumerate all modules */
4395 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4399 if (abuilder->modules) {
4400 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4401 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4402 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4403 if (!is_ok (&error)) {
4405 mono_reflection_free_type_info (&info);
4406 mono_error_set_pending_exception (&error);
4414 if (!type && abuilder->loaded_modules) {
4415 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4416 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4417 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4418 if (!is_ok (&error)) {
4420 mono_reflection_free_type_info (&info);
4421 mono_error_set_pending_exception (&error);
4430 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4431 if (!is_ok (&error)) {
4433 mono_reflection_free_type_info (&info);
4434 mono_error_set_pending_exception (&error);
4439 mono_reflection_free_type_info (&info);
4441 MonoException *e = NULL;
4444 e = mono_get_exception_type_load (name, NULL);
4447 mono_set_pending_exception (e);
4451 if (type->type == MONO_TYPE_CLASS) {
4452 MonoClass *klass = mono_type_get_class (type);
4454 /* need to report exceptions ? */
4455 if (throwOnError && mono_class_has_failure (klass)) {
4456 /* report SecurityException (or others) that occured when loading the assembly */
4457 mono_error_set_for_class_failure (&error, klass);
4458 mono_error_set_pending_exception (&error);
4463 /* g_print ("got it\n"); */
4464 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4465 mono_error_set_pending_exception (&error);
4471 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4474 gchar *shadow_ini_file;
4477 /* Check for shadow-copied assembly */
4478 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4479 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4481 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4482 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4488 g_free (shadow_ini_file);
4489 if (content != NULL) {
4492 *filename = content;
4499 ICALL_EXPORT MonoString *
4500 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4502 MonoDomain *domain = mono_object_domain (assembly);
4503 MonoAssembly *mass = assembly->assembly;
4504 MonoString *res = NULL;
4509 if (g_path_is_absolute (mass->image->name)) {
4510 absolute = g_strdup (mass->image->name);
4511 dirname = g_path_get_dirname (absolute);
4513 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4514 dirname = g_strdup (mass->basedir);
4517 replace_shadow_path (domain, dirname, &absolute);
4520 mono_icall_make_platform_path (absolute);
4523 uri = g_filename_to_uri (absolute, NULL, NULL);
4525 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4526 uri = g_strconcat (prepend, absolute, NULL);
4530 res = mono_string_new (domain, uri);
4537 ICALL_EXPORT MonoBoolean
4538 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4540 MonoAssembly *mass = assembly->assembly;
4542 return mass->in_gac;
4545 ICALL_EXPORT MonoReflectionAssembly*
4546 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4551 MonoImageOpenStatus status;
4552 MonoReflectionAssembly* result = NULL;
4554 name = mono_string_to_utf8_checked (mname, &error);
4555 if (mono_error_set_pending_exception (&error))
4557 res = mono_assembly_load_with_partial_name (name, &status);
4563 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4565 mono_error_set_pending_exception (&error);
4569 ICALL_EXPORT MonoStringHandle
4570 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4572 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4573 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4574 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4577 ICALL_EXPORT MonoBoolean
4578 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4580 return assembly->assembly->ref_only;
4583 ICALL_EXPORT MonoStringHandle
4584 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4586 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4587 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4589 return mono_string_new_handle (domain, assembly->image->version, error);
4592 ICALL_EXPORT MonoReflectionMethod*
4593 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4596 MonoReflectionMethod *res = NULL;
4599 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4603 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4604 if (!mono_error_ok (&error))
4607 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4610 if (!mono_error_ok (&error))
4611 mono_error_set_pending_exception (&error);
4615 ICALL_EXPORT MonoReflectionModule*
4616 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4619 MonoReflectionModule *result = NULL;
4620 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4621 if (!mono_error_ok (&error))
4622 mono_error_set_pending_exception (&error);
4626 ICALL_EXPORT MonoArray*
4627 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4630 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4631 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4632 if (mono_error_set_pending_exception (&error))
4637 for (i = 0; i < table->rows; ++i) {
4638 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4639 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4644 ICALL_EXPORT MonoStringHandle
4645 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4648 guint8 aotid_sum = 0;
4649 MonoDomain* domain = mono_domain_get ();
4651 if (!domain->entry_assembly || !domain->entry_assembly->image)
4654 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4656 for (i = 0; i < 16; ++i)
4657 aotid_sum |= (*aotid)[i];
4662 gchar *guid = mono_guid_to_string((guint8*) aotid);
4663 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4668 static MonoAssemblyName*
4669 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4671 mono_error_init (error);
4672 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4674 mono_assembly_get_assemblyref (image, i, aname);
4675 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4676 /* name and culture are pointers into the image tables, but we need
4677 * real malloc'd strings (so that we can g_free() them later from
4678 * Mono.RuntimeMarshal.FreeAssemblyName) */
4679 aname->name = g_strdup (aname->name);
4680 aname->culture = g_strdup (aname->culture);
4681 /* Don't need the hash value in managed */
4682 aname->hash_value = NULL;
4683 aname->hash_len = 0;
4684 g_assert (aname->public_key == NULL);
4686 /* note: this function doesn't return the codebase on purpose (i.e. it can
4687 be used under partial trust as path information isn't present). */
4691 ICALL_EXPORT GPtrArray*
4692 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4694 mono_error_init (error);
4695 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4696 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4697 MonoImage *image = ass->image;
4699 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4700 int count = t->rows;
4702 GPtrArray *result = g_ptr_array_sized_new (count);
4704 for (int i = 0; i < count; i++) {
4705 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4708 g_ptr_array_add (result, aname);
4713 /* move this in some file in mono/util/ */
4715 g_concat_dir_and_file (const char *dir, const char *file)
4717 g_return_val_if_fail (dir != NULL, NULL);
4718 g_return_val_if_fail (file != NULL, NULL);
4721 * If the directory name doesn't have a / on the end, we need
4722 * to add one so we get a proper path to the file
4724 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4725 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4727 return g_strconcat (dir, file, NULL);
4731 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4734 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4736 guint32 cols [MONO_MANIFEST_SIZE];
4737 guint32 impl, file_idx;
4741 char *n = mono_string_to_utf8_checked (name, &error);
4742 if (mono_error_set_pending_exception (&error))
4745 for (i = 0; i < table->rows; ++i) {
4746 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4747 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4748 if (strcmp (val, n) == 0)
4752 if (i == table->rows)
4755 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4758 * this code should only be called after obtaining the
4759 * ResourceInfo and handling the other cases.
4761 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4762 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4764 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4765 if (mono_error_set_pending_exception (&error) || !module)
4769 module = assembly->assembly->image;
4772 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4773 if (mono_error_set_pending_exception (&error))
4775 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4777 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4780 ICALL_EXPORT gboolean
4781 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4784 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4786 guint32 cols [MONO_MANIFEST_SIZE];
4787 guint32 file_cols [MONO_FILE_SIZE];
4791 n = mono_string_to_utf8_checked (name, &error);
4792 if (mono_error_set_pending_exception (&error))
4794 for (i = 0; i < table->rows; ++i) {
4795 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4796 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4797 if (strcmp (val, n) == 0)
4801 if (i == table->rows)
4804 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4805 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4808 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4809 case MONO_IMPLEMENTATION_FILE:
4810 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4811 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4812 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4813 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4814 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4815 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4818 info->location = RESOURCE_LOCATION_EMBEDDED;
4821 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4822 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4823 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4824 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4825 mono_error_set_assembly_load (&error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4826 mono_error_set_pending_exception (&error);
4829 MonoReflectionAssembly *assm_obj;
4830 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4832 mono_error_set_pending_exception (&error);
4835 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4837 /* Obtain info recursively */
4838 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4839 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4842 case MONO_IMPLEMENTATION_EXP_TYPE:
4843 g_assert_not_reached ();
4851 ICALL_EXPORT MonoObject*
4852 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4855 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4856 MonoArray *result = NULL;
4861 /* check hash if needed */
4863 n = mono_string_to_utf8_checked (name, &error);
4864 if (mono_error_set_pending_exception (&error))
4867 for (i = 0; i < table->rows; ++i) {
4868 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4869 if (strcmp (val, n) == 0) {
4872 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4873 fn = mono_string_new (mono_object_domain (assembly), n);
4875 return (MonoObject*)fn;
4883 for (i = 0; i < table->rows; ++i) {
4884 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4888 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4889 if (mono_error_set_pending_exception (&error))
4894 for (i = 0; i < table->rows; ++i) {
4895 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4896 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4897 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4898 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4903 return (MonoObject*)result;
4906 ICALL_EXPORT MonoArray*
4907 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4910 MonoDomain *domain = mono_domain_get();
4913 int i, j, file_count = 0;
4914 MonoImage **modules;
4915 guint32 module_count, real_module_count;
4916 MonoTableInfo *table;
4917 guint32 cols [MONO_FILE_SIZE];
4918 MonoImage *image = assembly->assembly->image;
4920 g_assert (image != NULL);
4921 g_assert (!assembly_is_dynamic (assembly->assembly));
4923 table = &image->tables [MONO_TABLE_FILE];
4924 file_count = table->rows;
4926 modules = image->modules;
4927 module_count = image->module_count;
4929 real_module_count = 0;
4930 for (i = 0; i < module_count; ++i)
4932 real_module_count ++;
4934 klass = mono_class_get_module_class ();
4935 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
4936 if (mono_error_set_pending_exception (&error))
4939 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
4940 if (mono_error_set_pending_exception (&error))
4943 mono_array_setref (res, 0, image_obj);
4945 for (i = 0; i < module_count; ++i)
4947 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
4948 if (mono_error_set_pending_exception (&error))
4950 mono_array_setref (res, j, rm);
4954 for (i = 0; i < file_count; ++i, ++j) {
4955 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4956 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4957 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
4958 if (mono_error_set_pending_exception (&error))
4960 mono_array_setref (res, j, rm);
4963 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
4964 if (mono_error_set_pending_exception (&error))
4967 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4968 mono_error_set_assembly_load (&error, g_strdup (filename), "%s", "");
4969 mono_error_set_pending_exception (&error);
4972 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
4973 if (mono_error_set_pending_exception (&error))
4975 mono_array_setref (res, j, rm);
4982 ICALL_EXPORT MonoReflectionMethod*
4983 ves_icall_GetCurrentMethod (void)
4985 MonoReflectionMethod *res = NULL;
4988 MonoMethod *m = mono_method_get_last_managed ();
4991 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
4995 while (m->is_inflated)
4996 m = ((MonoMethodInflated*)m)->declaring;
4998 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
4999 mono_error_set_pending_exception (&error);
5005 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5008 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5011 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5012 //method is inflated, we should inflate it on the other class
5013 MonoGenericContext ctx;
5014 ctx.method_inst = inflated->context.method_inst;
5015 ctx.class_inst = inflated->context.class_inst;
5016 if (mono_class_is_ginst (klass))
5017 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5018 else if (mono_class_is_gtd (klass))
5019 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5020 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5021 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5025 mono_class_setup_methods (method->klass);
5026 if (mono_class_has_failure (method->klass))
5028 int mcount = mono_class_get_method_count (method->klass);
5029 for (i = 0; i < mcount; ++i) {
5030 if (method->klass->methods [i] == method) {
5035 mono_class_setup_methods (klass);
5036 if (mono_class_has_failure (klass))
5038 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5039 return klass->methods [offset];
5042 ICALL_EXPORT MonoReflectionMethod*
5043 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5045 MonoReflectionMethod *res = NULL;
5048 if (type && generic_check) {
5049 klass = mono_class_from_mono_type (type);
5050 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5053 if (method->klass != klass) {
5054 method = mono_method_get_equivalent_method (method, klass);
5059 klass = mono_class_from_mono_type (type);
5061 klass = method->klass;
5062 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5063 mono_error_set_pending_exception (&error);
5067 ICALL_EXPORT MonoReflectionMethodBody*
5068 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5071 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5072 mono_error_set_pending_exception (&error);
5076 ICALL_EXPORT MonoReflectionAssembly*
5077 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5080 MonoReflectionAssembly *result;
5081 MonoMethod *dest = NULL;
5083 mono_stack_walk_no_il (get_executing, &dest);
5085 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5087 mono_error_set_pending_exception (&error);
5092 ICALL_EXPORT MonoReflectionAssembly*
5093 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5096 MonoReflectionAssembly *result;
5097 MonoDomain* domain = mono_domain_get ();
5099 if (!domain->entry_assembly)
5102 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5104 mono_error_set_pending_exception (&error);
5108 ICALL_EXPORT MonoReflectionAssembly*
5109 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5114 MonoReflectionAssembly *result;
5117 mono_stack_walk_no_il (get_executing, &dest);
5119 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5123 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5126 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5128 mono_error_set_pending_exception (&error);
5132 ICALL_EXPORT MonoStringHandle
5133 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5134 gboolean assembly_qualified, MonoError *error)
5136 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5137 MonoType *type = MONO_HANDLE_RAW (object)->type;
5138 MonoTypeNameFormat format;
5139 MonoStringHandle res;
5143 format = assembly_qualified ?
5144 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5145 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5147 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5149 name = mono_type_get_name_full (type, format);
5151 return NULL_HANDLE_STRING;
5153 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5155 return NULL_HANDLE_STRING;
5158 res = mono_string_new_handle (domain, name, error);
5165 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5168 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5170 mono_class_init_checked (klass, &error);
5171 mono_error_set_pending_exception (&error);
5172 return mono_security_core_clr_class_level (klass);
5176 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5178 MonoClassField *field = rfield->field;
5179 return mono_security_core_clr_field_level (field, TRUE);
5183 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5185 MonoMethod *method = rfield->method;
5186 return mono_security_core_clr_method_level (method, TRUE);
5189 ICALL_EXPORT MonoString *
5190 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5192 MonoDomain *domain = mono_object_domain (assembly);
5193 MonoAssembly *mass = assembly->assembly;
5197 name = mono_stringify_assembly_name (&mass->aname);
5198 res = mono_string_new (domain, name);
5204 ICALL_EXPORT MonoAssemblyName *
5205 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5207 return &mass->aname;
5211 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5214 MonoImageOpenStatus status = MONO_IMAGE_OK;
5215 char *codebase = NULL;
5220 mono_error_init (error);
5222 filename = mono_string_handle_to_utf8 (fname, error);
5223 return_if_nok (error);
5225 dirname = g_path_get_dirname (filename);
5226 replace_shadow_path (mono_domain_get (), dirname, &filename);
5229 image = mono_image_open (filename, &status);
5232 if (status == MONO_IMAGE_IMAGE_INVALID)
5233 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5235 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5240 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5242 mono_image_close (image);
5244 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5248 if (filename != NULL && *filename != '\0') {
5251 codebase = g_strdup (filename);
5253 mono_icall_make_platform_path (codebase);
5255 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5257 result = g_strconcat (prepend, codebase, NULL);
5261 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5264 mono_image_close (image);
5268 ICALL_EXPORT MonoBoolean
5269 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5270 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5272 MonoBoolean result = FALSE;
5273 MonoDeclSecurityEntry entry;
5275 /* SecurityAction.RequestMinimum */
5276 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5277 *minimum = entry.blob;
5278 *minLength = entry.size;
5281 /* SecurityAction.RequestOptional */
5282 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5283 *optional = entry.blob;
5284 *optLength = entry.size;
5287 /* SecurityAction.RequestRefuse */
5288 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5289 *refused = entry.blob;
5290 *refLength = entry.size;
5298 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5300 guint32 attrs, visibility;
5302 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5303 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5304 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5307 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5313 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5315 mono_error_init (error);
5316 HANDLE_FUNCTION_ENTER ();
5317 MonoError klass_error;
5318 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5321 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5322 return_if_nok (error);
5324 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5326 MonoException *ex = mono_error_convert_to_exception (error);
5327 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5329 HANDLE_FUNCTION_RETURN ();
5332 static MonoArrayHandle
5333 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5335 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5338 mono_error_init (error);
5340 /* we start the count from 1 because we skip the special type <Module> */
5343 for (i = 1; i < tdef->rows; ++i) {
5344 if (mono_module_type_is_visible (tdef, image, i + 1))
5348 count = tdef->rows - 1;
5350 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5351 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5352 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5353 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5355 for (i = 1; i < tdef->rows; ++i) {
5356 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5357 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5358 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5367 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5369 HANDLE_FUNCTION_ENTER ();
5370 mono_error_init (error);
5371 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5372 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5376 /* Append the new types to the end of the array */
5377 if (mono_array_handle_length (res2) > 0) {
5380 len1 = mono_array_handle_length (res);
5381 len2 = mono_array_handle_length (res2);
5383 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5387 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5388 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5389 MONO_HANDLE_ASSIGN (res, res3);
5391 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5395 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5396 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5397 MONO_HANDLE_ASSIGN (exceptions, ex3);
5400 HANDLE_FUNCTION_RETURN ();
5404 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5406 HANDLE_FUNCTION_ENTER ();
5407 MonoError unboxed_error;
5408 mono_error_init (&unboxed_error);
5409 mono_error_set_for_class_failure (&unboxed_error, klass);
5411 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5412 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5413 HANDLE_FUNCTION_RETURN ();
5416 ICALL_EXPORT MonoArrayHandle
5417 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5419 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5422 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5423 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5425 g_assert (!assembly_is_dynamic (assembly));
5426 MonoImage *image = assembly->image;
5427 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5428 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5429 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5431 /* Append data from all modules in the assembly */
5432 for (i = 0; i < table->rows; ++i) {
5433 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5434 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5435 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5438 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5439 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5444 /* the ReflectionTypeLoadException must have all the types (Types property),
5445 * NULL replacing types which throws an exception. The LoaderException must
5446 * contain all exceptions for NULL items.
5449 int len = mono_array_handle_length (res);
5453 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5454 for (i = 0; i < len; i++) {
5455 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5457 if (!MONO_HANDLE_IS_NULL (t)) {
5458 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5459 if ((klass != NULL) && mono_class_has_failure (klass)) {
5460 /* keep the class in the list */
5461 list = g_list_append (list, klass);
5462 /* and replace Type with NULL */
5463 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5470 if (list || ex_count) {
5472 int j, length = g_list_length (list) + ex_count;
5474 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5475 if (!is_ok (error)) {
5477 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5479 /* Types for which mono_class_get_checked () succeeded */
5480 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5481 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5482 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5484 /* Types for which it don't */
5485 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5486 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5487 if (!MONO_HANDLE_IS_NULL (exc)) {
5488 g_assert (i < length);
5489 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5496 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5497 if (!is_ok (error)) {
5498 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5500 mono_error_set_exception_handle (error, exc);
5501 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5508 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5510 mono_assembly_name_free (aname);
5515 ICALL_EXPORT gboolean
5516 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5518 *is_version_definited = *is_token_defined = FALSE;
5520 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5523 ICALL_EXPORT MonoReflectionTypeHandle
5524 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5526 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5527 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5532 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5534 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5535 /* These images do not have a global type */
5538 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5542 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5548 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5550 /*if (module->image)
5551 mono_image_close (module->image);*/
5554 ICALL_EXPORT MonoStringHandle
5555 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5557 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5558 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5561 return mono_string_new_handle (domain, image->guid, error);
5565 static inline gpointer
5566 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5568 return (gpointer) (-1);
5570 #endif /* HOST_WIN32 */
5572 ICALL_EXPORT gpointer
5573 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5575 return mono_icall_module_get_hinstance (module);
5579 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5581 if (image_is_dynamic (image)) {
5582 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5583 *pe_kind = dyn->pe_kind;
5584 *machine = dyn->machine;
5587 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5588 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5593 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5595 return (image->md_version_major << 16) | (image->md_version_minor);
5598 ICALL_EXPORT MonoArrayHandle
5599 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5601 mono_error_init (error);
5603 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5604 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5607 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5610 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5611 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5612 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5614 int n = mono_array_handle_length (exceptions);
5615 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5616 for (int i = 0; i < n; ++i) {
5617 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5618 if (!MONO_HANDLE_IS_NULL (ex)) {
5619 mono_error_set_exception_handle (error, ex);
5620 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5628 mono_memberref_is_method (MonoImage *image, guint32 token)
5630 if (!image_is_dynamic (image)) {
5631 guint32 cols [MONO_MEMBERREF_SIZE];
5633 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5634 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5635 mono_metadata_decode_blob_size (sig, &sig);
5636 return (*sig != 0x6);
5639 MonoClass *handle_class;
5641 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5642 mono_error_cleanup (&error); /* just probing, ignore error */
5646 return mono_defaults.methodhandle_class == handle_class;
5651 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5654 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5655 mono_array_addr (type_args, MonoType*, 0));
5657 context->class_inst = NULL;
5659 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5660 mono_array_addr (method_args, MonoType*, 0));
5662 context->method_inst = NULL;
5665 ICALL_EXPORT MonoType*
5666 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5669 int table = mono_metadata_token_table (token);
5670 int index = mono_metadata_token_index (token);
5671 MonoGenericContext context;
5674 *resolve_error = ResolveTokenError_Other;
5676 /* Validate token */
5677 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5678 (table != MONO_TABLE_TYPESPEC)) {
5679 *resolve_error = ResolveTokenError_BadTable;
5683 if (image_is_dynamic (image)) {
5684 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5685 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5686 mono_error_cleanup (&error);
5687 return klass ? &klass->byval_arg : NULL;
5690 init_generic_context_from_args (&context, type_args, method_args);
5691 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5692 mono_error_cleanup (&error);
5693 return klass ? &klass->byval_arg : NULL;
5696 if ((index <= 0) || (index > image->tables [table].rows)) {
5697 *resolve_error = ResolveTokenError_OutOfRange;
5701 init_generic_context_from_args (&context, type_args, method_args);
5702 klass = mono_class_get_checked (image, token, &error);
5704 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5705 if (!mono_error_ok (&error)) {
5706 mono_error_set_pending_exception (&error);
5711 return &klass->byval_arg;
5716 ICALL_EXPORT MonoMethod*
5717 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5720 int table = mono_metadata_token_table (token);
5721 int index = mono_metadata_token_index (token);
5722 MonoGenericContext context;
5725 *resolve_error = ResolveTokenError_Other;
5727 /* Validate token */
5728 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5729 (table != MONO_TABLE_MEMBERREF)) {
5730 *resolve_error = ResolveTokenError_BadTable;
5734 if (image_is_dynamic (image)) {
5735 if (table == MONO_TABLE_METHOD) {
5736 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5737 mono_error_cleanup (&error);
5741 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5742 *resolve_error = ResolveTokenError_BadTable;
5746 init_generic_context_from_args (&context, type_args, method_args);
5747 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5748 mono_error_cleanup (&error);
5752 if ((index <= 0) || (index > image->tables [table].rows)) {
5753 *resolve_error = ResolveTokenError_OutOfRange;
5756 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5757 *resolve_error = ResolveTokenError_BadTable;
5761 init_generic_context_from_args (&context, type_args, method_args);
5762 method = mono_get_method_checked (image, token, NULL, &context, &error);
5763 mono_error_set_pending_exception (&error);
5768 ICALL_EXPORT MonoString*
5769 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5772 int index = mono_metadata_token_index (token);
5774 *resolve_error = ResolveTokenError_Other;
5776 /* Validate token */
5777 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5778 *resolve_error = ResolveTokenError_BadTable;
5782 if (image_is_dynamic (image)) {
5783 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5784 mono_error_cleanup (&error);
5788 if ((index <= 0) || (index >= image->heap_us.size)) {
5789 *resolve_error = ResolveTokenError_OutOfRange;
5793 /* FIXME: What to do if the index points into the middle of a string ? */
5795 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5796 mono_error_set_pending_exception (&error);
5800 ICALL_EXPORT MonoClassField*
5801 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5805 int table = mono_metadata_token_table (token);
5806 int index = mono_metadata_token_index (token);
5807 MonoGenericContext context;
5808 MonoClassField *field;
5810 *resolve_error = ResolveTokenError_Other;
5812 /* Validate token */
5813 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5814 *resolve_error = ResolveTokenError_BadTable;
5818 if (image_is_dynamic (image)) {
5819 if (table == MONO_TABLE_FIELD) {
5820 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5821 mono_error_cleanup (&error);
5825 if (mono_memberref_is_method (image, token)) {
5826 *resolve_error = ResolveTokenError_BadTable;
5830 init_generic_context_from_args (&context, type_args, method_args);
5831 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5832 mono_error_cleanup (&error);
5836 if ((index <= 0) || (index > image->tables [table].rows)) {
5837 *resolve_error = ResolveTokenError_OutOfRange;
5840 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5841 *resolve_error = ResolveTokenError_BadTable;
5845 init_generic_context_from_args (&context, type_args, method_args);
5846 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5847 mono_error_set_pending_exception (&error);
5853 ICALL_EXPORT MonoObject*
5854 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5858 int table = mono_metadata_token_table (token);
5860 *error = ResolveTokenError_Other;
5863 case MONO_TABLE_TYPEDEF:
5864 case MONO_TABLE_TYPEREF:
5865 case MONO_TABLE_TYPESPEC: {
5866 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5868 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5869 mono_error_set_pending_exception (&merror);
5876 case MONO_TABLE_METHOD:
5877 case MONO_TABLE_METHODSPEC: {
5878 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5880 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5881 mono_error_set_pending_exception (&merror);
5887 case MONO_TABLE_FIELD: {
5888 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5890 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5891 mono_error_set_pending_exception (&merror);
5897 case MONO_TABLE_MEMBERREF:
5898 if (mono_memberref_is_method (image, token)) {
5899 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5901 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5902 mono_error_set_pending_exception (&merror);
5909 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5911 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5912 mono_error_set_pending_exception (&merror);
5921 *error = ResolveTokenError_BadTable;
5927 ICALL_EXPORT MonoArray*
5928 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5931 int table = mono_metadata_token_table (token);
5932 int idx = mono_metadata_token_index (token);
5933 MonoTableInfo *tables = image->tables;
5938 *resolve_error = ResolveTokenError_OutOfRange;
5940 /* FIXME: Support other tables ? */
5941 if (table != MONO_TABLE_STANDALONESIG)
5944 if (image_is_dynamic (image))
5947 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5950 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5952 ptr = mono_metadata_blob_heap (image, sig);
5953 len = mono_metadata_decode_blob_size (ptr, &ptr);
5955 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
5956 if (mono_error_set_pending_exception (&error))
5958 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5962 ICALL_EXPORT MonoBoolean
5963 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
5969 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5975 check_for_invalid_type (MonoClass *klass, MonoError *error)
5979 mono_error_init (error);
5981 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
5984 name = mono_type_get_full_name (klass);
5985 mono_error_set_type_load_name (error, name, g_strdup (""), "");
5987 ICALL_EXPORT MonoReflectionType *
5988 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
5991 MonoReflectionType *ret;
5992 MonoClass *klass, *aklass;
5994 klass = mono_class_from_mono_type (type->type);
5995 check_for_invalid_type (klass, &error);
5996 if (mono_error_set_pending_exception (&error))
5999 if (rank == 0) //single dimentional array
6000 aklass = mono_array_class_get (klass, 1);
6002 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6004 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6005 mono_error_set_pending_exception (&error);
6010 ICALL_EXPORT MonoReflectionType *
6011 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6014 MonoReflectionType *ret;
6017 klass = mono_class_from_mono_type (type->type);
6018 mono_class_init_checked (klass, &error);
6019 if (mono_error_set_pending_exception (&error))
6022 check_for_invalid_type (klass, &error);
6023 if (mono_error_set_pending_exception (&error))
6026 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6027 mono_error_set_pending_exception (&error);
6032 ICALL_EXPORT MonoReflectionType *
6033 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6036 MonoReflectionType *ret;
6037 MonoClass *klass, *pklass;
6039 klass = mono_class_from_mono_type (type->type);
6040 mono_class_init_checked (klass, &error);
6041 if (mono_error_set_pending_exception (&error))
6043 check_for_invalid_type (klass, &error);
6044 if (mono_error_set_pending_exception (&error))
6047 pklass = mono_ptr_class_get (type->type);
6049 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6050 mono_error_set_pending_exception (&error);
6055 ICALL_EXPORT MonoObject *
6056 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6057 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6060 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6061 MonoObject *delegate;
6063 MonoMethod *method = info->method;
6064 MonoMethodSignature *sig = mono_method_signature(method);
6066 mono_class_init_checked (delegate_class, &error);
6067 if (mono_error_set_pending_exception (&error))
6070 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6071 /* FIXME improve this exception message */
6072 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6074 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6075 mono_error_set_pending_exception (&error);
6079 if (mono_security_core_clr_enabled ()) {
6080 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6081 if (throwOnBindFailure)
6082 mono_error_set_pending_exception (&error);
6084 mono_error_cleanup (&error);
6089 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6090 if (!method->is_inflated) {
6091 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"));
6096 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6097 if (mono_error_set_pending_exception (&error))
6100 if (method_is_dynamic (method)) {
6101 /* Creating a trampoline would leak memory */
6102 func = mono_compile_method_checked (method, &error);
6103 if (mono_error_set_pending_exception (&error))
6106 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6107 method = mono_object_get_virtual_method (target, method);
6108 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6109 if (mono_error_set_pending_exception (&error))
6111 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6114 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6115 if (mono_error_set_pending_exception (&error))
6120 ICALL_EXPORT MonoMulticastDelegate *
6121 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6124 MonoMulticastDelegate *ret;
6126 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6128 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6129 if (mono_error_set_pending_exception (&error))
6132 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6137 ICALL_EXPORT MonoReflectionMethod*
6138 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6140 MonoReflectionMethod *ret = NULL;
6142 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6143 mono_error_set_pending_exception (&error);
6149 static inline gint32
6150 mono_array_get_byte_length (MonoArray *array)
6156 klass = array->obj.vtable->klass;
6158 if (array->bounds == NULL)
6159 length = array->max_length;
6162 for (i = 0; i < klass->rank; ++ i)
6163 length *= array->bounds [i].length;
6166 switch (klass->element_class->byval_arg.type) {
6169 case MONO_TYPE_BOOLEAN:
6173 case MONO_TYPE_CHAR:
6181 return length * sizeof (gpointer);
6192 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6194 return mono_array_get_byte_length (array);
6198 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6200 return mono_array_get (array, gint8, idx);
6204 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6206 mono_array_set (array, gint8, idx, value);
6209 ICALL_EXPORT MonoBoolean
6210 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6212 guint8 *src_buf, *dest_buf;
6215 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6219 g_assert (count >= 0);
6221 /* This is called directly from the class libraries without going through the managed wrapper */
6222 MONO_CHECK_ARG_NULL (src, FALSE);
6223 MONO_CHECK_ARG_NULL (dest, FALSE);
6225 /* watch out for integer overflow */
6226 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6229 src_buf = (guint8 *)src->vector + src_offset;
6230 dest_buf = (guint8 *)dest->vector + dest_offset;
6233 memcpy (dest_buf, src_buf, count);
6235 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6240 #ifndef DISABLE_REMOTING
6241 ICALL_EXPORT MonoObject *
6242 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6245 MonoDomain *domain = mono_object_domain (this_obj);
6247 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6248 MonoTransparentProxy *tp;
6252 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6253 if (mono_error_set_pending_exception (&error))
6256 tp = (MonoTransparentProxy*) res;
6258 MONO_OBJECT_SETREF (tp, rp, rp);
6259 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6260 klass = mono_class_from_mono_type (type);
6262 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6263 mono_class_setup_vtable (klass);
6264 if (mono_class_has_failure (klass)) {
6265 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6269 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6270 if (mono_error_set_pending_exception (&error))
6272 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6273 if (mono_error_set_pending_exception (&error))
6276 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6277 if (mono_error_set_pending_exception (&error))
6282 ICALL_EXPORT MonoReflectionType *
6283 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6286 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6287 mono_error_set_pending_exception (&error);
6293 /* System.Environment */
6296 ves_icall_System_Environment_get_UserName (void)
6298 /* using glib is more portable */
6299 return mono_string_new (mono_domain_get (), g_get_user_name ());
6304 mono_icall_get_machine_name (void)
6306 #if !defined(DISABLE_SOCKETS)
6310 #if defined _SC_HOST_NAME_MAX
6311 n = sysconf (_SC_HOST_NAME_MAX);
6315 buf = g_malloc (n+1);
6317 if (gethostname (buf, n) == 0){
6319 result = mono_string_new (mono_domain_get (), buf);
6326 return mono_string_new (mono_domain_get (), "mono");
6329 #endif /* !HOST_WIN32 */
6331 ICALL_EXPORT MonoString *
6332 ves_icall_System_Environment_get_MachineName (void)
6334 return mono_icall_get_machine_name ();
6339 mono_icall_get_platform (void)
6341 #if defined(__MACH__)
6344 // Notice that the value is hidden from user code, and only exposed
6345 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6346 // define and making assumptions based on Unix/128/4 values before there
6347 // was a MacOS define. Lots of code would assume that not-Unix meant
6348 // Windows, but in this case, it would be OSX.
6356 #endif /* !HOST_WIN32 */
6359 ves_icall_System_Environment_get_Platform (void)
6361 return mono_icall_get_platform ();
6365 static inline MonoString *
6366 mono_icall_get_new_line (void)
6368 return mono_string_new (mono_domain_get (), "\n");
6370 #endif /* !HOST_WIN32 */
6372 ICALL_EXPORT MonoString *
6373 ves_icall_System_Environment_get_NewLine (void)
6375 return mono_icall_get_new_line ();
6379 static inline MonoBoolean
6380 mono_icall_is_64bit_os (void)
6382 #if SIZEOF_VOID_P == 8
6385 #if defined(HAVE_SYS_UTSNAME_H)
6386 struct utsname name;
6388 if (uname (&name) >= 0) {
6389 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6395 #endif /* !HOST_WIN32 */
6397 ICALL_EXPORT MonoBoolean
6398 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6400 return mono_icall_is_64bit_os ();
6403 ICALL_EXPORT MonoStringHandle
6404 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6408 if (utf8_name == NULL)
6409 return NULL_HANDLE_STRING;
6411 value = g_getenv (utf8_name);
6414 return NULL_HANDLE_STRING;
6416 return mono_string_new_handle (mono_domain_get (), value, error);
6420 * There is no standard way to get at environ.
6423 #ifndef __MINGW32_VERSION
6424 #if defined(__APPLE__)
6425 #if defined (TARGET_OSX)
6426 /* Apple defines this in crt_externs.h but doesn't provide that header for
6427 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6428 * in fact exist on all implementations (so far)
6430 gchar ***_NSGetEnviron(void);
6431 #define environ (*_NSGetEnviron())
6433 static char *mono_environ[1] = { NULL };
6434 #define environ mono_environ
6435 #endif /* defined (TARGET_OSX) */
6443 ICALL_EXPORT MonoArray *
6444 ves_icall_System_Environment_GetCoomandLineArgs (void)
6447 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6448 mono_error_set_pending_exception (&error);
6454 mono_icall_get_environment_variable_names (void)
6464 for (e = environ; *e != 0; ++ e)
6467 domain = mono_domain_get ();
6468 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6469 if (mono_error_set_pending_exception (&error))
6473 for (e = environ; *e != 0; ++ e) {
6474 parts = g_strsplit (*e, "=", 2);
6476 str = mono_string_new (domain, *parts);
6477 mono_array_setref (names, n, str);
6487 #endif /* !HOST_WIN32 */
6489 ICALL_EXPORT MonoArray *
6490 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6492 return mono_icall_get_environment_variable_names ();
6497 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6499 gchar *utf8_name, *utf8_value;
6502 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6503 if (mono_error_set_pending_exception (&error))
6506 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6507 g_unsetenv (utf8_name);
6512 utf8_value = mono_string_to_utf8_checked (value, &error);
6513 if (!mono_error_ok (&error)) {
6515 mono_error_set_pending_exception (&error);
6518 g_setenv (utf8_name, utf8_value, TRUE);
6521 g_free (utf8_value);
6523 #endif /* !HOST_WIN32 */
6526 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6528 mono_icall_set_environment_variable (name, value);
6532 ves_icall_System_Environment_Exit (int result)
6534 mono_environment_exitcode_set (result);
6536 /* FIXME: There are some cleanup hangs that should be worked out, but
6537 * if the program is going to exit, everything will be cleaned up when
6538 * NaCl exits anyway.
6540 #ifndef __native_client__
6541 if (!mono_runtime_try_shutdown ())
6542 mono_thread_exit ();
6544 /* Suspend all managed threads since the runtime is going away */
6545 mono_thread_suspend_all_other_threads ();
6547 mono_runtime_quit ();
6550 /* we may need to do some cleanup here... */
6554 ICALL_EXPORT MonoStringHandle
6555 ves_icall_System_Environment_GetGacPath (MonoError *error)
6557 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6561 static inline MonoString *
6562 mono_icall_get_windows_folder_path (int folder)
6564 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6565 return mono_string_new (mono_domain_get (), "");
6567 #endif /* !HOST_WIN32 */
6569 ICALL_EXPORT MonoString*
6570 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6572 return mono_icall_get_windows_folder_path (folder);
6575 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6577 mono_icall_get_logical_drives (void)
6580 gunichar2 buf [256], *ptr, *dname;
6582 guint initial_size = 127, size = 128;
6585 MonoString *drivestr;
6586 MonoDomain *domain = mono_domain_get ();
6592 while (size > initial_size) {
6593 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6594 if (size > initial_size) {
6597 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6598 initial_size = size;
6612 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6613 if (mono_error_set_pending_exception (&error))
6620 while (*u16) { u16++; len ++; }
6621 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6622 if (mono_error_set_pending_exception (&error))
6625 mono_array_setref (result, ndrives++, drivestr);
6635 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6637 ICALL_EXPORT MonoArray *
6638 ves_icall_System_Environment_GetLogicalDrives (void)
6640 return mono_icall_get_logical_drives ();
6643 ICALL_EXPORT MonoString *
6644 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6647 gunichar2 volume_name [MAX_PATH + 1];
6649 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6651 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6652 mono_error_set_pending_exception (&error);
6656 ICALL_EXPORT MonoStringHandle
6657 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6659 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6662 static const char *encodings [] = {
6664 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6665 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6666 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6668 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6669 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6670 "x_unicode_2_0_utf_7",
6672 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6673 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6675 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6678 "unicodefffe", "utf_16be",
6685 * Returns the internal codepage, if the value of "int_code_page" is
6686 * 1 at entry, and we can not compute a suitable code page number,
6687 * returns the code page as a string
6689 ICALL_EXPORT MonoString*
6690 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6695 char *codepage = NULL;
6697 int want_name = *int_code_page;
6700 *int_code_page = -1;
6702 g_get_charset (&cset);
6703 c = codepage = g_strdup (cset);
6704 for (c = codepage; *c; c++){
6705 if (isascii (*c) && isalpha (*c))
6710 /* g_print ("charset: %s\n", cset); */
6712 /* handle some common aliases */
6715 for (i = 0; p != 0; ){
6718 p = encodings [++i];
6721 if (strcmp (p, codepage) == 0){
6722 *int_code_page = code;
6725 p = encodings [++i];
6728 if (strstr (codepage, "utf_8") != NULL)
6729 *int_code_page |= 0x10000000;
6732 if (want_name && *int_code_page == -1)
6733 return mono_string_new (mono_domain_get (), cset);
6738 ICALL_EXPORT MonoBoolean
6739 ves_icall_System_Environment_get_HasShutdownStarted (void)
6741 if (mono_runtime_is_shutting_down ())
6744 if (mono_domain_is_unloading (mono_domain_get ()))
6752 mono_icall_broadcast_setting_change (void)
6756 #endif /* !HOST_WIN32 */
6759 ves_icall_System_Environment_BroadcastSettingChange (void)
6761 mono_icall_broadcast_setting_change ();
6766 ves_icall_System_Environment_get_TickCount (void)
6768 /* this will overflow after ~24 days */
6769 return (gint32) (mono_msec_boottime () & 0xffffffff);
6773 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6778 #ifndef DISABLE_REMOTING
6779 ICALL_EXPORT MonoBoolean
6780 ves_icall_IsTransparentProxy (MonoObject *proxy)
6785 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6791 ICALL_EXPORT MonoReflectionMethod *
6792 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6793 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6795 MonoReflectionMethod *ret = NULL;
6800 MonoMethod **vtable;
6801 MonoMethod *res = NULL;
6803 MONO_CHECK_ARG_NULL (rtype, NULL);
6804 MONO_CHECK_ARG_NULL (rmethod, NULL);
6806 method = rmethod->method;
6807 klass = mono_class_from_mono_type (rtype->type);
6808 mono_class_init_checked (klass, &error);
6809 if (mono_error_set_pending_exception (&error))
6812 if (MONO_CLASS_IS_INTERFACE (klass))
6815 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6818 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6819 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6825 mono_class_setup_vtable (klass);
6826 vtable = klass->vtable;
6828 if (mono_class_is_interface (method->klass)) {
6829 gboolean variance_used = FALSE;
6830 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6831 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6833 res = vtable [offs + method->slot];
6835 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6838 if (method->slot != -1)
6839 res = vtable [method->slot];
6845 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6846 mono_error_set_pending_exception (&error);
6851 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6857 klass = mono_class_from_mono_type (type->type);
6858 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6859 if (!is_ok (&error)) {
6860 mono_error_set_pending_exception (&error);
6864 mono_vtable_set_is_remote (vtable, enable);
6867 #else /* DISABLE_REMOTING */
6870 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6872 g_assert_not_reached ();
6877 ICALL_EXPORT MonoObject *
6878 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6885 domain = mono_object_domain (type);
6886 klass = mono_class_from_mono_type (type->type);
6887 mono_class_init_checked (klass, &error);
6888 if (mono_error_set_pending_exception (&error))
6891 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6892 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6896 if (klass->rank >= 1) {
6897 g_assert (klass->rank == 1);
6898 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6899 mono_error_set_pending_exception (&error);
6902 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6903 if (!is_ok (&error)) {
6904 mono_error_set_pending_exception (&error);
6907 /* Bypass remoting object creation check */
6908 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6909 mono_error_set_pending_exception (&error);
6915 ICALL_EXPORT MonoStringHandle
6916 ves_icall_System_IO_get_temp_path (MonoError *error)
6918 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6921 #ifndef PLATFORM_NO_DRIVEINFO
6922 ICALL_EXPORT MonoBoolean
6923 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
6924 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
6928 ULARGE_INTEGER wapi_free_bytes_avail;
6929 ULARGE_INTEGER wapi_total_number_of_bytes;
6930 ULARGE_INTEGER wapi_total_number_of_free_bytes;
6932 *error = ERROR_SUCCESS;
6933 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
6934 &wapi_total_number_of_free_bytes);
6937 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
6938 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
6939 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
6941 *free_bytes_avail = 0;
6942 *total_number_of_bytes = 0;
6943 *total_number_of_free_bytes = 0;
6944 *error = GetLastError ();
6950 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6951 static inline guint32
6952 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
6954 return GetDriveType (mono_string_chars (root_path_name));
6956 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6958 ICALL_EXPORT guint32
6959 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
6961 return mono_icall_drive_info_get_drive_type (root_path_name);
6964 #endif /* PLATFORM_NO_DRIVEINFO */
6966 ICALL_EXPORT gpointer
6967 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
6970 gpointer result = mono_compile_method_checked (method, &error);
6971 mono_error_set_pending_exception (&error);
6975 ICALL_EXPORT MonoString *
6976 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6981 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6983 mono_icall_make_platform_path (path);
6985 mcpath = mono_string_new (mono_domain_get (), path);
6991 /* this is an icall */
6993 get_bundled_app_config (void)
6996 const gchar *app_config;
6999 gchar *config_file_name, *config_file_path;
7000 gsize len, config_file_path_length, config_ext_length;
7003 domain = mono_domain_get ();
7004 file = domain->setup->configuration_file;
7005 if (!file || file->length == 0)
7008 // Retrieve config file and remove the extension
7009 config_file_name = mono_string_to_utf8_checked (file, &error);
7010 if (mono_error_set_pending_exception (&error))
7012 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7013 if (!config_file_path)
7014 config_file_path = config_file_name;
7016 config_file_path_length = strlen (config_file_path);
7017 config_ext_length = strlen (".config");
7018 if (config_file_path_length <= config_ext_length)
7021 len = config_file_path_length - config_ext_length;
7022 module = (gchar *)g_malloc0 (len + 1);
7023 memcpy (module, config_file_path, len);
7024 // Get the config file from the module name
7025 app_config = mono_config_string_for_assembly_file (module);
7028 if (config_file_name != config_file_path)
7029 g_free (config_file_name);
7030 g_free (config_file_path);
7035 return mono_string_new (mono_domain_get (), app_config);
7038 static MonoStringHandle
7039 get_bundled_machine_config (MonoError *error)
7041 const gchar *machine_config;
7043 machine_config = mono_get_machine_config ();
7045 if (!machine_config)
7046 return NULL_HANDLE_STRING;
7048 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7051 ICALL_EXPORT MonoStringHandle
7052 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7054 return get_bundled_machine_config (error);
7058 ICALL_EXPORT MonoStringHandle
7059 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7061 return get_bundled_machine_config (error);
7064 ICALL_EXPORT MonoStringHandle
7065 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7067 return get_bundled_machine_config (error);
7071 ICALL_EXPORT MonoString *
7072 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7077 path = g_path_get_dirname (mono_get_config_dir ());
7079 mono_icall_make_platform_path (path);
7081 ipath = mono_string_new (mono_domain_get (), path);
7087 ICALL_EXPORT gboolean
7088 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7090 MonoPEResourceDataEntry *entry;
7093 if (!assembly || !result || !size)
7098 image = assembly->assembly->image;
7099 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7103 *result = mono_image_rva_map (image, entry->rde_data_offset);
7108 *size = entry->rde_size;
7113 ICALL_EXPORT MonoBoolean
7114 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7116 return mono_is_debugger_attached ();
7119 ICALL_EXPORT MonoBoolean
7120 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7122 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7123 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7129 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7131 if (mono_get_runtime_callbacks ()->debug_log)
7132 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7137 mono_icall_write_windows_debug_string (MonoString *message)
7139 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7141 #endif /* !HOST_WIN32 */
7144 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7146 mono_icall_write_windows_debug_string (message);
7149 /* Only used for value types */
7150 ICALL_EXPORT MonoObject *
7151 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7158 domain = mono_object_domain (type);
7159 klass = mono_class_from_mono_type (type->type);
7160 mono_class_init_checked (klass, &error);
7161 if (mono_error_set_pending_exception (&error))
7164 if (mono_class_is_nullable (klass))
7165 /* No arguments -> null */
7168 result = mono_object_new_checked (domain, klass, &error);
7169 mono_error_set_pending_exception (&error);
7173 ICALL_EXPORT MonoReflectionMethod *
7174 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7176 MonoReflectionMethod *ret = NULL;
7179 MonoClass *klass, *parent;
7180 MonoGenericContext *generic_inst = NULL;
7181 MonoMethod *method = m->method;
7182 MonoMethod *result = NULL;
7185 if (method->klass == NULL)
7188 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7189 MONO_CLASS_IS_INTERFACE (method->klass) ||
7190 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7193 slot = mono_method_get_vtable_slot (method);
7197 klass = method->klass;
7198 if (mono_class_is_ginst (klass)) {
7199 generic_inst = mono_class_get_context (klass);
7200 klass = mono_class_get_generic_class (klass)->container_class;
7205 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7206 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7207 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7208 or klass is the generic container class and generic_inst is the instantiation.
7210 when we go to the parent, if the parent is an open constructed type, we need to
7211 replace the type parameters by the definitions from the generic_inst, and then take it
7212 apart again into the klass and the generic_inst.
7214 For cases like this:
7215 class C<T> : B<T, int> {
7216 public override void Foo () { ... }
7218 class B<U,V> : A<HashMap<U,V>> {
7219 public override void Foo () { ... }
7222 public virtual void Foo () { ... }
7225 if at each iteration the parent isn't open, we can skip inflating it. if at some
7226 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7229 MonoGenericContext *parent_inst = NULL;
7230 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7231 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7232 if (!mono_error_ok (&error)) {
7233 mono_error_set_pending_exception (&error);
7237 if (mono_class_is_ginst (parent)) {
7238 parent_inst = mono_class_get_context (parent);
7239 parent = mono_class_get_generic_class (parent)->container_class;
7242 mono_class_setup_vtable (parent);
7243 if (parent->vtable_size <= slot)
7246 generic_inst = parent_inst;
7249 klass = klass->parent;
7252 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7253 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7254 if (!mono_error_ok (&error)) {
7255 mono_error_set_pending_exception (&error);
7259 generic_inst = NULL;
7261 if (mono_class_is_ginst (klass)) {
7262 generic_inst = mono_class_get_context (klass);
7263 klass = mono_class_get_generic_class (klass)->container_class;
7269 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7270 if (!mono_error_ok (&error)) {
7271 mono_error_set_pending_exception (&error);
7276 if (klass == method->klass)
7279 /*This is possible if definition == FALSE.
7280 * Do it here to be really sure we don't read invalid memory.
7282 if (slot >= klass->vtable_size)
7285 mono_class_setup_vtable (klass);
7287 result = klass->vtable [slot];
7288 if (result == NULL) {
7289 /* It is an abstract method */
7290 gboolean found = FALSE;
7291 gpointer iter = NULL;
7292 while ((result = mono_class_get_methods (klass, &iter))) {
7293 if (result->slot == slot) {
7298 /* found might be FALSE if we looked in an abstract class
7299 * that doesn't override an abstract method of its
7301 * abstract class Base {
7302 * public abstract void Foo ();
7304 * abstract class Derived : Base { }
7305 * class Child : Derived {
7306 * public override void Foo () { }
7309 * if m was Child.Foo and we ask for the base method,
7310 * then we get here with klass == Derived and found == FALSE
7312 /* but it shouldn't be the case that if we're looking
7313 * for the definition and didn't find a result; the
7314 * loop above should've taken us as far as we could
7316 g_assert (!(definition && !found));
7321 g_assert (result != NULL);
7323 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7324 mono_error_set_pending_exception (&error);
7328 ICALL_EXPORT MonoString*
7329 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7331 MonoMethod *method = m->method;
7333 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7338 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7340 iter->sig = *(MonoMethodSignature**)argsp;
7342 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7343 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7346 /* FIXME: it's not documented what start is exactly... */
7350 iter->args = argsp + sizeof (gpointer);
7352 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7354 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7357 ICALL_EXPORT MonoTypedRef
7358 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7360 guint32 i, arg_size;
7364 i = iter->sig->sentinelpos + iter->next_arg;
7366 g_assert (i < iter->sig->param_count);
7368 res.type = iter->sig->params [i];
7369 res.klass = mono_class_from_mono_type (res.type);
7370 arg_size = mono_type_stack_size (res.type, &align);
7371 #if defined(__arm__) || defined(__mips__)
7372 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7374 res.value = iter->args;
7375 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7376 /* Values are stored as 8 byte register sized objects, but 'value'
7377 * is dereferenced as a pointer in other routines.
7379 res.value = (char*)res.value + 4;
7381 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7382 if (arg_size <= sizeof (gpointer)) {
7384 int padding = arg_size - mono_type_size (res.type, &dummy);
7385 res.value = (guint8*)res.value + padding;
7388 iter->args = (char*)iter->args + arg_size;
7391 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7396 ICALL_EXPORT MonoTypedRef
7397 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7399 guint32 i, arg_size;
7403 i = iter->sig->sentinelpos + iter->next_arg;
7405 g_assert (i < iter->sig->param_count);
7407 while (i < iter->sig->param_count) {
7408 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7410 res.type = iter->sig->params [i];
7411 res.klass = mono_class_from_mono_type (res.type);
7412 /* FIXME: endianess issue... */
7413 arg_size = mono_type_stack_size (res.type, &align);
7414 #if defined(__arm__) || defined(__mips__)
7415 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7417 res.value = iter->args;
7418 iter->args = (char*)iter->args + arg_size;
7420 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7423 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7431 ICALL_EXPORT MonoType*
7432 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7436 i = iter->sig->sentinelpos + iter->next_arg;
7438 g_assert (i < iter->sig->param_count);
7440 return iter->sig->params [i];
7443 ICALL_EXPORT MonoObject*
7444 mono_TypedReference_ToObject (MonoTypedRef* tref)
7447 MonoObject *result = NULL;
7448 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7449 MonoObject** objp = (MonoObject **)tref->value;
7453 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7454 mono_error_set_pending_exception (&error);
7458 ICALL_EXPORT MonoTypedRef
7459 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7462 MonoReflectionField *f;
7464 MonoType *ftype = NULL;
7468 memset (&res, 0, sizeof (res));
7471 g_assert (mono_array_length (fields) > 0);
7473 klass = target->vtable->klass;
7475 for (i = 0; i < mono_array_length (fields); ++i) {
7476 f = mono_array_get (fields, MonoReflectionField*, i);
7478 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7481 if (f->field->parent != klass) {
7482 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7486 p = (guint8*)target + f->field->offset;
7488 p += f->field->offset - sizeof (MonoObject);
7489 klass = mono_class_from_mono_type (f->field->type);
7490 ftype = f->field->type;
7494 res.klass = mono_class_from_mono_type (ftype);
7501 prelink_method (MonoMethod *method, MonoError *error)
7503 const char *exc_class, *exc_arg;
7505 mono_error_init (error);
7506 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7508 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7510 mono_error_set_exception_instance (error,
7511 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7514 /* create the wrapper, too? */
7518 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7522 prelink_method (method->method, &error);
7523 mono_error_set_pending_exception (&error);
7527 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7530 MonoClass *klass = mono_class_from_mono_type (type->type);
7532 gpointer iter = NULL;
7534 mono_class_init_checked (klass, &error);
7535 if (mono_error_set_pending_exception (&error))
7538 while ((m = mono_class_get_methods (klass, &iter))) {
7539 prelink_method (m, &error);
7540 if (mono_error_set_pending_exception (&error))
7545 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7547 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7548 gint32 const **exponents,
7549 gunichar2 const **digitLowerTable,
7550 gunichar2 const **digitUpperTable,
7551 gint64 const **tenPowersList,
7552 gint32 const **decHexDigits)
7554 *mantissas = Formatter_MantissaBitsTable;
7555 *exponents = Formatter_TensExponentTable;
7556 *digitLowerTable = Formatter_DigitLowerTable;
7557 *digitUpperTable = Formatter_DigitUpperTable;
7558 *tenPowersList = Formatter_TenPowersList;
7559 *decHexDigits = Formatter_DecHexDigits;
7563 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7564 * and avoid useless allocations.
7567 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7569 MonoReflectionType *rt;
7573 mono_error_init (error);
7574 for (i = 0; i < type->num_mods; ++i) {
7575 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7580 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7581 return_val_if_nok (error, NULL);
7583 for (i = 0; i < type->num_mods; ++i) {
7584 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7585 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7586 return_val_if_nok (error, NULL);
7588 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7589 return_val_if_nok (error, NULL);
7591 mono_array_setref (res, count, rt);
7598 ICALL_EXPORT MonoArray*
7599 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7602 MonoType *type = param->ClassImpl->type;
7603 MonoClass *member_class = mono_object_class (param->MemberImpl);
7604 MonoMethod *method = NULL;
7607 MonoMethodSignature *sig;
7610 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7611 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7612 method = rmethod->method;
7613 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7614 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7615 if (!(method = prop->property->get))
7616 method = prop->property->set;
7619 char *type_name = mono_type_get_full_name (member_class);
7620 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7621 MonoException *ex = mono_get_exception_not_supported (msg);
7624 mono_set_pending_exception (ex);
7628 image = method->klass->image;
7629 pos = param->PositionImpl;
7630 sig = mono_method_signature (method);
7634 type = sig->params [pos];
7636 res = type_array_from_modifiers (image, type, optional, &error);
7637 mono_error_set_pending_exception (&error);
7642 get_property_type (MonoProperty *prop)
7644 MonoMethodSignature *sig;
7646 sig = mono_method_signature (prop->get);
7648 } else if (prop->set) {
7649 sig = mono_method_signature (prop->set);
7650 return sig->params [sig->param_count - 1];
7655 ICALL_EXPORT MonoArray*
7656 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7659 MonoType *type = get_property_type (property->property);
7660 MonoImage *image = property->klass->image;
7665 res = type_array_from_modifiers (image, type, optional, &error);
7666 mono_error_set_pending_exception (&error);
7671 *Construct a MonoType suited to be used to decode a constant blob object.
7673 * @type is the target type which will be constructed
7674 * @blob_type is the blob type, for example, that comes from the constant table
7675 * @real_type is the expected constructed type.
7678 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7680 type->type = blob_type;
7681 type->data.klass = NULL;
7682 if (blob_type == MONO_TYPE_CLASS)
7683 type->data.klass = mono_defaults.object_class;
7684 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7685 /* For enums, we need to use the base type */
7686 type->type = MONO_TYPE_VALUETYPE;
7687 type->data.klass = mono_class_from_mono_type (real_type);
7689 type->data.klass = mono_class_from_mono_type (real_type);
7692 ICALL_EXPORT MonoObject*
7693 property_info_get_default_value (MonoReflectionProperty *property)
7697 MonoProperty *prop = property->property;
7698 MonoType *type = get_property_type (prop);
7699 MonoDomain *domain = mono_object_domain (property);
7700 MonoTypeEnum def_type;
7701 const char *def_value;
7704 mono_class_init (prop->parent);
7706 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7707 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7711 def_value = mono_class_get_property_default_value (prop, &def_type);
7713 mono_type_from_blob_type (&blob_type, def_type, type);
7714 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7716 mono_error_set_pending_exception (&error);
7720 ICALL_EXPORT MonoBoolean
7721 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7724 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7725 MonoCustomAttrInfo *cinfo;
7728 mono_class_init_checked (attr_class, &error);
7729 if (mono_error_set_pending_exception (&error))
7732 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7733 if (!is_ok (&error)) {
7734 mono_error_set_pending_exception (&error);
7739 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7741 mono_custom_attrs_free (cinfo);
7745 ICALL_EXPORT MonoArray*
7746 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7748 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7753 mono_class_init_checked (attr_class, &error);
7754 if (mono_error_set_pending_exception (&error))
7758 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7759 if (!mono_error_ok (&error)) {
7760 mono_error_set_pending_exception (&error);
7767 ICALL_EXPORT MonoArray*
7768 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7772 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7773 mono_error_set_pending_exception (&error);
7778 ICALL_EXPORT MonoStringHandle
7779 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7782 MonoStringHandle display_name;
7784 mono_error_init (error);
7785 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7786 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7788 return display_name;
7791 ICALL_EXPORT MonoString*
7792 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7795 MonoString *message;
7799 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7800 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7803 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7805 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7806 if (mono_error_set_pending_exception (&error))
7814 static inline gint32
7815 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7817 return WAIT_TIMEOUT;
7819 #endif /* !HOST_WIN32 */
7822 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7824 return mono_icall_wait_for_input_idle (handle, milliseconds);
7828 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7830 return mono_process_current_pid ();
7833 ICALL_EXPORT MonoBoolean
7834 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7846 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7848 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7852 ICALL_EXPORT MonoObject*
7853 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7855 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7860 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7862 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7866 ICALL_EXPORT MonoObject*
7867 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7869 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7873 ICALL_EXPORT MonoBoolean
7874 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7876 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7881 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7883 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7887 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7889 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7894 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7896 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7900 ICALL_EXPORT mono_unichar2*
7901 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7903 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7910 #ifndef DISABLE_ICALL_TABLES
7912 #define ICALL_TYPE(id,name,first)
7913 #define ICALL(id,name,func) Icall_ ## id,
7914 #define HANDLES(inner) inner
7917 #include "metadata/icall-def.h"
7923 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7924 #define ICALL(id,name,func)
7926 #define HANDLES(inner) inner
7928 #include "metadata/icall-def.h"
7934 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7935 #define ICALL(id,name,func)
7937 #define HANDLES(inner) inner
7939 guint16 first_icall;
7942 static const IcallTypeDesc
7943 icall_type_descs [] = {
7944 #include "metadata/icall-def.h"
7948 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7951 #define HANDLES(inner) inner
7953 #define ICALL_TYPE(id,name,first)
7956 #ifdef HAVE_ARRAY_ELEM_INIT
7957 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7958 #define MSGSTRFIELD1(line) str##line
7960 static const struct msgstrtn_t {
7961 #define ICALL(id,name,func)
7963 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7964 #include "metadata/icall-def.h"
7966 } icall_type_names_str = {
7967 #define ICALL_TYPE(id,name,first) (name),
7968 #include "metadata/icall-def.h"
7971 static const guint16 icall_type_names_idx [] = {
7972 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7973 #include "metadata/icall-def.h"
7976 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7978 static const struct msgstr_t {
7980 #define ICALL_TYPE(id,name,first)
7981 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7982 #include "metadata/icall-def.h"
7984 } icall_names_str = {
7985 #define ICALL(id,name,func) (name),
7986 #include "metadata/icall-def.h"
7989 static const guint16 icall_names_idx [] = {
7990 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7991 #include "metadata/icall-def.h"
7994 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8000 #define ICALL_TYPE(id,name,first) name,
8001 #define ICALL(id,name,func)
8002 static const char* const
8003 icall_type_names [] = {
8004 #include "metadata/icall-def.h"
8008 #define icall_type_name_get(id) (icall_type_names [(id)])
8012 #define ICALL_TYPE(id,name,first)
8013 #define ICALL(id,name,func) name,
8014 static const char* const
8016 #include "metadata/icall-def.h"
8019 #define icall_name_get(id) icall_names [(id)]
8021 #endif /* !HAVE_ARRAY_ELEM_INIT */
8024 #define HANDLES(inner) inner
8027 #define ICALL_TYPE(id,name,first)
8028 #define ICALL(id,name,func) func,
8029 static const gconstpointer
8030 icall_functions [] = {
8031 #include "metadata/icall-def.h"
8035 #ifdef ENABLE_ICALL_SYMBOL_MAP
8037 #define HANDLES(inner) inner
8040 #define ICALL_TYPE(id,name,first)
8041 #define ICALL(id,name,func) #func,
8042 static const gconstpointer
8043 icall_symbols [] = {
8044 #include "metadata/icall-def.h"
8051 #define ICALL_TYPE(id,name,first)
8052 #define ICALL(id,name,func) 0,
8054 #define HANDLES(inner) 1,
8056 icall_uses_handles [] = {
8057 #include "metadata/icall-def.h"
8062 #endif /* DISABLE_ICALL_TABLES */
8064 static mono_mutex_t icall_mutex;
8065 static GHashTable *icall_hash = NULL;
8066 static GHashTable *jit_icall_hash_name = NULL;
8067 static GHashTable *jit_icall_hash_addr = NULL;
8070 mono_icall_init (void)
8072 #ifndef DISABLE_ICALL_TABLES
8075 /* check that tables are sorted: disable in release */
8078 const char *prev_class = NULL;
8079 const char *prev_method;
8081 for (i = 0; i < Icall_type_num; ++i) {
8082 const IcallTypeDesc *desc;
8085 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8086 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8087 prev_class = icall_type_name_get (i);
8088 desc = &icall_type_descs [i];
8089 num_icalls = icall_desc_num_icalls (desc);
8090 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8091 for (j = 0; j < num_icalls; ++j) {
8092 const char *methodn = icall_name_get (desc->first_icall + j);
8093 if (prev_method && strcmp (prev_method, methodn) >= 0)
8094 g_print ("method %s should come before method %s\n", methodn, prev_method);
8095 prev_method = methodn;
8101 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8102 mono_os_mutex_init (&icall_mutex);
8106 mono_icall_lock (void)
8108 mono_locks_os_acquire (&icall_mutex, IcallLock);
8112 mono_icall_unlock (void)
8114 mono_locks_os_release (&icall_mutex, IcallLock);
8118 mono_icall_cleanup (void)
8120 g_hash_table_destroy (icall_hash);
8121 g_hash_table_destroy (jit_icall_hash_name);
8122 g_hash_table_destroy (jit_icall_hash_addr);
8123 mono_os_mutex_destroy (&icall_mutex);
8127 * mono_add_internal_call:
8128 * @name: method specification to surface to the managed world
8129 * @method: pointer to a C method to invoke when the method is called
8131 * This method surfaces the C function pointed by @method as a method
8132 * that has been surfaced in managed code with the method specified in
8133 * @name as an internal call.
8135 * Internal calls are surfaced to all app domains loaded and they are
8136 * accessibly by a type with the specified name.
8138 * You must provide a fully qualified type name, that is namespaces
8139 * and type name, followed by a colon and the method name, with an
8140 * optional signature to bind.
8142 * For example, the following are all valid declarations:
8144 * "MyApp.Services.ScriptService:Accelerate"
8145 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8147 * You use method parameters in cases where there might be more than
8148 * one surface method to managed code. That way you can register different
8149 * internal calls for different method overloads.
8151 * The internal calls are invoked with no marshalling. This means that .NET
8152 * types like System.String are exposed as `MonoString *` parameters. This is
8153 * different than the way that strings are surfaced in P/Invoke.
8155 * For more information on how the parameters are marshalled, see the
8156 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8159 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8160 * reference for more information on the format of method descriptions.
8163 mono_add_internal_call (const char *name, gconstpointer method)
8167 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8169 mono_icall_unlock ();
8172 #ifndef DISABLE_ICALL_TABLES
8174 #ifdef HAVE_ARRAY_ELEM_INIT
8176 compare_method_imap (const void *key, const void *elem)
8178 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8179 return strcmp (key, method_name);
8183 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8185 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);
8188 return (nameslot - &icall_names_idx [0]);
8192 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8194 gsize slotnum = find_slot_icall (imap, name);
8197 return (gboolean)icall_uses_handles [slotnum];
8201 find_method_icall (const IcallTypeDesc *imap, const char *name)
8203 gsize slotnum = find_slot_icall (imap, name);
8206 return (gpointer)icall_functions [slotnum];
8210 compare_class_imap (const void *key, const void *elem)
8212 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8213 return strcmp (key, class_name);
8216 static const IcallTypeDesc*
8217 find_class_icalls (const char *name)
8219 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);
8222 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8225 #else /* HAVE_ARRAY_ELEM_INIT */
8228 compare_method_imap (const void *key, const void *elem)
8230 const char** method_name = (const char**)elem;
8231 return strcmp (key, *method_name);
8235 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8237 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8240 return nameslot - icall_names;
8244 find_method_icall (const IcallTypeDesc *imap, const char *name)
8246 gsize slotnum = find_slot_icall (imap, name);
8249 return (gpointer)icall_functions [slotnum];
8253 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8255 gsize slotnum = find_slot_icall (imap, name);
8258 return (gboolean)icall_uses_handles [slotnum];
8262 compare_class_imap (const void *key, const void *elem)
8264 const char** class_name = (const char**)elem;
8265 return strcmp (key, *class_name);
8268 static const IcallTypeDesc*
8269 find_class_icalls (const char *name)
8271 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8274 return &icall_type_descs [nameslot - icall_type_names];
8277 #endif /* HAVE_ARRAY_ELEM_INIT */
8279 #endif /* DISABLE_ICALL_TABLES */
8282 * we should probably export this as an helper (handle nested types).
8283 * Returns the number of chars written in buf.
8286 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8288 int nspacelen, cnamelen;
8289 nspacelen = strlen (klass->name_space);
8290 cnamelen = strlen (klass->name);
8291 if (nspacelen + cnamelen + 2 > bufsize)
8294 memcpy (buf, klass->name_space, nspacelen);
8295 buf [nspacelen ++] = '.';
8297 memcpy (buf + nspacelen, klass->name, cnamelen);
8298 buf [nspacelen + cnamelen] = 0;
8299 return nspacelen + cnamelen;
8302 #ifdef DISABLE_ICALL_TABLES
8304 no_icall_table (void)
8306 g_assert_not_reached ();
8311 * mono_lookup_internal_call_full:
8312 * @method: the method to look up
8313 * @uses_handles: out argument if method needs handles around managed objects.
8315 * Returns a pointer to the icall code for the given method. If
8316 * uses_handles is not NULL, it will be set to TRUE if the method
8317 * needs managed objects wrapped using the infrastructure in handle.h
8319 * If the method is not found, warns and returns NULL.
8322 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8327 int typelen = 0, mlen, siglen;
8329 #ifndef DISABLE_ICALL_TABLES
8330 const IcallTypeDesc *imap = NULL;
8333 g_assert (method != NULL);
8335 if (method->is_inflated)
8336 method = ((MonoMethodInflated *) method)->declaring;
8338 if (method->klass->nested_in) {
8339 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8343 mname [pos++] = '/';
8346 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8352 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8357 #ifndef DISABLE_ICALL_TABLES
8358 imap = find_class_icalls (mname);
8361 mname [typelen] = ':';
8362 mname [typelen + 1] = ':';
8364 mlen = strlen (method->name);
8365 memcpy (mname + typelen + 2, method->name, mlen);
8366 sigstart = mname + typelen + 2 + mlen;
8369 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8370 siglen = strlen (tmpsig);
8371 if (typelen + mlen + siglen + 6 > sizeof (mname))
8374 memcpy (sigstart + 1, tmpsig, siglen);
8375 sigstart [siglen + 1] = ')';
8376 sigstart [siglen + 2] = 0;
8381 res = g_hash_table_lookup (icall_hash, mname);
8384 *uses_handles = FALSE;
8385 mono_icall_unlock ();;
8388 /* try without signature */
8390 res = g_hash_table_lookup (icall_hash, mname);
8393 *uses_handles = FALSE;
8394 mono_icall_unlock ();
8398 #ifdef DISABLE_ICALL_TABLES
8399 mono_icall_unlock ();
8400 /* Fail only when the result is actually used */
8401 /* mono_marshal_get_native_wrapper () depends on this */
8402 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8403 return ves_icall_System_String_ctor_RedirectToCreateString;
8405 return no_icall_table;
8407 /* it wasn't found in the static call tables */
8410 *uses_handles = FALSE;
8411 mono_icall_unlock ();
8414 res = find_method_icall (imap, sigstart - mlen);
8417 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8418 mono_icall_unlock ();
8421 /* try _with_ signature */
8423 res = find_method_icall (imap, sigstart - mlen);
8426 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8427 mono_icall_unlock ();
8431 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8432 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8433 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8434 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8435 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");
8436 g_print ("If you see other errors or faults after this message they are probably related\n");
8437 g_print ("and you need to fix your mono install first.\n");
8439 mono_icall_unlock ();
8446 mono_lookup_internal_call (MonoMethod *method)
8448 return mono_lookup_internal_call_full (method, NULL);
8451 #ifdef ENABLE_ICALL_SYMBOL_MAP
8453 func_cmp (gconstpointer key, gconstpointer p)
8455 return (gsize)key - (gsize)*(gsize*)p;
8460 * mono_lookup_icall_symbol:
8462 * Given the icall METHOD, returns its C symbol.
8465 mono_lookup_icall_symbol (MonoMethod *m)
8467 #ifdef DISABLE_ICALL_TABLES
8468 g_assert_not_reached ();
8471 #ifdef ENABLE_ICALL_SYMBOL_MAP
8475 static gconstpointer *functions_sorted;
8476 static const char**symbols_sorted;
8477 static gboolean inited;
8482 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8483 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8484 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8485 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8486 /* Bubble sort the two arrays */
8490 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8491 if (functions_sorted [i] > functions_sorted [i + 1]) {
8494 tmp = functions_sorted [i];
8495 functions_sorted [i] = functions_sorted [i + 1];
8496 functions_sorted [i + 1] = tmp;
8497 tmp = symbols_sorted [i];
8498 symbols_sorted [i] = symbols_sorted [i + 1];
8499 symbols_sorted [i + 1] = tmp;
8506 func = mono_lookup_internal_call (m);
8509 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8513 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8515 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8516 g_assert_not_reached ();
8523 type_from_typename (char *type_name)
8525 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8527 if (!strcmp (type_name, "int"))
8528 klass = mono_defaults.int_class;
8529 else if (!strcmp (type_name, "ptr"))
8530 klass = mono_defaults.int_class;
8531 else if (!strcmp (type_name, "void"))
8532 klass = mono_defaults.void_class;
8533 else if (!strcmp (type_name, "int32"))
8534 klass = mono_defaults.int32_class;
8535 else if (!strcmp (type_name, "uint32"))
8536 klass = mono_defaults.uint32_class;
8537 else if (!strcmp (type_name, "int8"))
8538 klass = mono_defaults.sbyte_class;
8539 else if (!strcmp (type_name, "uint8"))
8540 klass = mono_defaults.byte_class;
8541 else if (!strcmp (type_name, "int16"))
8542 klass = mono_defaults.int16_class;
8543 else if (!strcmp (type_name, "uint16"))
8544 klass = mono_defaults.uint16_class;
8545 else if (!strcmp (type_name, "long"))
8546 klass = mono_defaults.int64_class;
8547 else if (!strcmp (type_name, "ulong"))
8548 klass = mono_defaults.uint64_class;
8549 else if (!strcmp (type_name, "float"))
8550 klass = mono_defaults.single_class;
8551 else if (!strcmp (type_name, "double"))
8552 klass = mono_defaults.double_class;
8553 else if (!strcmp (type_name, "object"))
8554 klass = mono_defaults.object_class;
8555 else if (!strcmp (type_name, "obj"))
8556 klass = mono_defaults.object_class;
8557 else if (!strcmp (type_name, "string"))
8558 klass = mono_defaults.string_class;
8559 else if (!strcmp (type_name, "bool"))
8560 klass = mono_defaults.boolean_class;
8561 else if (!strcmp (type_name, "boolean"))
8562 klass = mono_defaults.boolean_class;
8564 g_error ("%s", type_name);
8565 g_assert_not_reached ();
8567 return &klass->byval_arg;
8571 * LOCKING: Take the corlib image lock.
8573 MonoMethodSignature*
8574 mono_create_icall_signature (const char *sigstr)
8579 MonoMethodSignature *res, *res2;
8580 MonoImage *corlib = mono_defaults.corlib;
8582 mono_image_lock (corlib);
8583 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8584 mono_image_unlock (corlib);
8589 parts = g_strsplit (sigstr, " ", 256);
8598 res = mono_metadata_signature_alloc (corlib, len - 1);
8603 * Under windows, the default pinvoke calling convention is STDCALL but
8606 res->call_convention = MONO_CALL_C;
8609 res->ret = type_from_typename (parts [0]);
8610 for (i = 1; i < len; ++i) {
8611 res->params [i - 1] = type_from_typename (parts [i]);
8616 mono_image_lock (corlib);
8617 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8619 res = res2; /*Value is allocated in the image pool*/
8621 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8622 mono_image_unlock (corlib);
8628 mono_find_jit_icall_by_name (const char *name)
8630 MonoJitICallInfo *info;
8631 g_assert (jit_icall_hash_name);
8634 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8635 mono_icall_unlock ();
8640 mono_find_jit_icall_by_addr (gconstpointer addr)
8642 MonoJitICallInfo *info;
8643 g_assert (jit_icall_hash_addr);
8646 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8647 mono_icall_unlock ();
8653 * mono_get_jit_icall_info:
8655 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8656 * caller should access it while holding the icall lock.
8659 mono_get_jit_icall_info (void)
8661 return jit_icall_hash_name;
8665 * mono_lookup_jit_icall_symbol:
8667 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8670 mono_lookup_jit_icall_symbol (const char *name)
8672 MonoJitICallInfo *info;
8673 const char *res = NULL;
8676 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8678 res = info->c_symbol;
8679 mono_icall_unlock ();
8684 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8687 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8688 mono_icall_unlock ();
8692 * 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
8693 * icalls without wrappers in some cases.
8696 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8698 MonoJitICallInfo *info;
8705 if (!jit_icall_hash_name) {
8706 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8707 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8710 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8711 g_warning ("jit icall already defined \"%s\"\n", name);
8712 g_assert_not_reached ();
8715 info = g_new0 (MonoJitICallInfo, 1);
8720 info->c_symbol = c_symbol;
8721 info->no_raise = no_raise;
8724 info->wrapper = func;
8726 info->wrapper = NULL;
8729 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8730 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8732 mono_icall_unlock ();
8737 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8739 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);