5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool.h>
40 #include <mono/metadata/threadpool-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/w32socket.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/metadata-internals.h>
56 #include <mono/metadata/class-internals.h>
57 #include <mono/metadata/reflection-internals.h>
58 #include <mono/metadata/marshal.h>
59 #include <mono/metadata/gc-internals.h>
60 #include <mono/metadata/mono-gc.h>
61 #include <mono/metadata/rand.h>
62 #include <mono/metadata/sysmath.h>
63 #include <mono/metadata/appdomain-icalls.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssemblyHandle ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
120 static MonoArrayHandle
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array, MonoClassField *field_handle, MonoError *error)
846 mono_error_init (error);
848 MonoClass *klass = mono_handle_class (array);
849 guint32 size = mono_array_element_size (klass);
850 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
852 const char *field_data;
854 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
855 mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type");
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 mono_error_set_argument (error, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle));
864 size *= MONO_HANDLE_GETVAL(array, max_length);
865 field_data = mono_field_get_data (field_handle);
867 if (size > mono_type_size (field_handle->type, &align)) {
868 mono_error_set_argument (error, "field_handle", "Field not large enough to fill array");
872 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
874 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
875 guint ## n *src = (guint ## n *) field_data; \
877 nEnt = (size / sizeof(guint ## n)); \
879 for (i = 0; i < nEnt; i++) { \
880 data[i] = read ## n (&src[i]); \
884 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
886 switch (type->type) {
903 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
907 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
912 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
914 return offsetof (MonoString, chars);
917 ICALL_EXPORT MonoObject *
918 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
920 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
924 MonoObject *ret = mono_object_clone_checked (obj, &error);
925 mono_error_set_pending_exception (&error);
932 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
938 MONO_CHECK_ARG_NULL (handle,);
940 klass = mono_class_from_mono_type (handle);
941 MONO_CHECK_ARG (handle, klass,);
943 if (mono_class_is_gtd (klass))
946 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
947 if (!is_ok (&error)) {
948 mono_error_set_pending_exception (&error);
952 /* This will call the type constructor */
953 if (!mono_runtime_class_init_full (vtable, &error))
954 mono_error_set_pending_exception (&error);
958 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
962 mono_image_check_for_module_cctor (image);
963 if (image->has_module_cctor) {
964 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
965 if (!mono_error_ok (&error)) {
966 mono_error_set_pending_exception (&error);
969 /*It's fine to raise the exception here*/
970 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
971 if (!is_ok (&error)) {
972 mono_error_set_pending_exception (&error);
975 if (!mono_runtime_class_init_full (vtable, &error))
976 mono_error_set_pending_exception (&error);
980 ICALL_EXPORT MonoBoolean
981 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
983 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
984 // It does not work on win32
990 MonoInternalThread *thread;
992 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
993 /* if we have no info we are optimistic and assume there is enough room */
997 thread = mono_thread_internal_current ();
998 // .net seems to check that at least 50% of stack is available
999 min_size = thread->stack_size / 2;
1001 // TODO: It's not always set
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionTypeHandle
1216 ves_icall_System_Object_GetType (MonoObjectHandle obj, MonoError *error)
1218 mono_error_init (error);
1219 MonoDomain *domain = MONO_HANDLE_DOMAIN (obj);
1220 MonoClass *klass = mono_handle_class (obj);
1221 #ifndef DISABLE_REMOTING
1222 if (mono_class_is_transparent_proxy (klass)) {
1223 MonoTransparentProxyHandle proxy_obj = MONO_HANDLE_CAST (MonoTransparentProxy, obj);
1224 MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (proxy_obj, remote_class);
1225 MonoType *proxy_type = &remote_class->proxy_class->byval_arg;
1226 return mono_type_get_object_handle (domain, proxy_type, error);
1229 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
1233 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1235 MonoMethod **dest = (MonoMethod **)data;
1237 /* skip unmanaged frames */
1242 if (!strcmp (m->klass->name_space, "System.Reflection"))
1251 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1253 MonoMethod **dest = (MonoMethod **)data;
1255 /* skip unmanaged frames */
1259 if (m->wrapper_type != MONO_WRAPPER_NONE)
1267 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1278 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1280 MonoMethod **dest = (MonoMethod **)data;
1282 /* skip unmanaged frames */
1286 if (m->wrapper_type != MONO_WRAPPER_NONE)
1294 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1295 || (!strcmp (m->klass->name_space, "System"))))
1305 static MonoReflectionTypeHandle
1306 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1308 MonoMethod *m, *dest;
1310 MonoType *type = NULL;
1311 MonoAssembly *assembly = NULL;
1312 gboolean type_resolve = FALSE;
1313 MonoImage *rootimage = NULL;
1315 mono_error_init (error);
1318 * We must compute the calling assembly as type loading must happen under a metadata context.
1319 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1320 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1322 m = mono_method_get_last_managed ();
1324 if (m && m->klass->image != mono_defaults.corlib) {
1325 /* Happens with inlining */
1327 /* Ugly hack: type_from_parsed_name is called from
1328 * System.Type.internal_from_name, which is called most
1329 * directly from System.Type.GetType(string,bool,bool) but
1330 * also indirectly from places such as
1331 * System.Type.GetType(string,func,func) (via
1332 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1333 * so we need to skip over all of those to find the true caller.
1335 * It would be nice if we had stack marks.
1337 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1343 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1344 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1345 * to crash. This only seems to happen in some strange remoting
1346 * scenarios and I was unable to figure out what's happening there.
1347 * Dec 10, 2005 - Martin.
1351 assembly = dest->klass->image->assembly;
1352 type_resolve = TRUE;
1353 rootimage = assembly->image;
1355 g_warning (G_STRLOC);
1357 *caller_assembly = assembly;
1359 if (info->assembly.name)
1360 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1363 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1364 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1370 // Say we're looking for System.Generic.Dict<int, Local>
1371 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1372 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1373 // is messed up when we go to construct the Local as the type arg...
1375 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1376 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1377 if (!info->assembly.name && !type) {
1379 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1383 if (assembly && !type && type_resolve) {
1384 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1385 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1393 return mono_type_get_object_handle (mono_domain_get (), type, error);
1395 return MONO_HANDLE_NEW (MonoReflectionType, NULL);
1398 ICALL_EXPORT MonoReflectionTypeHandle
1399 ves_icall_System_Type_internal_from_name (MonoStringHandle name,
1400 MonoBoolean throwOnError,
1401 MonoBoolean ignoreCase,
1404 mono_error_init (error);
1405 MonoTypeNameParse info;
1407 MonoAssembly *caller_assembly;
1408 MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1410 char *str = mono_string_handle_to_utf8 (name, error);
1414 parsedOk = mono_reflection_parse_type (str, &info);
1416 /* mono_reflection_parse_type() mangles the string */
1418 mono_reflection_free_type_info (&info);
1420 mono_error_set_argument (error, "typeName", "failed parse: %s", str);
1424 MONO_HANDLE_ASSIGN (type, type_from_parsed_name (&info, ignoreCase, &caller_assembly, error));
1426 if (!is_ok (error)) {
1427 mono_reflection_free_type_info (&info);
1431 if (MONO_HANDLE_IS_NULL (type)) {
1433 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1435 if (info.assembly.name)
1436 aname = mono_stringify_assembly_name (&info.assembly);
1437 else if (caller_assembly)
1438 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1440 aname = g_strdup ("");
1441 mono_error_set_type_load_name (error, tname, aname, "");
1443 mono_reflection_free_type_info (&info);
1449 if (!is_ok (error)) {
1451 mono_error_cleanup (error);
1452 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
1459 ICALL_EXPORT MonoReflectionTypeHandle
1460 ves_icall_System_Type_internal_from_handle (MonoType *handle, MonoError *error)
1462 mono_error_init (error);
1463 MonoDomain *domain = mono_domain_get ();
1465 return mono_type_get_object_handle (domain, handle, error);
1468 ICALL_EXPORT MonoType*
1469 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1471 return mono_class_get_type (klass);
1475 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1477 g_ptr_array_free (ptr_array, TRUE);
1481 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1487 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1490 char *res = mono_string_to_utf8_checked (s, &error);
1491 mono_error_set_pending_exception (&error);
1495 /* System.TypeCode */
1514 TYPECODE_STRING = 18
1517 ICALL_EXPORT guint32
1518 ves_icall_type_GetTypeCodeInternal (MonoReflectionTypeHandle ref_type, MonoError *error)
1520 mono_error_init (error);
1521 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1525 return TYPECODE_OBJECT;
1529 case MONO_TYPE_VOID:
1530 return TYPECODE_OBJECT;
1531 case MONO_TYPE_BOOLEAN:
1532 return TYPECODE_BOOLEAN;
1534 return TYPECODE_BYTE;
1536 return TYPECODE_SBYTE;
1538 return TYPECODE_UINT16;
1540 return TYPECODE_INT16;
1541 case MONO_TYPE_CHAR:
1542 return TYPECODE_CHAR;
1546 return TYPECODE_OBJECT;
1548 return TYPECODE_UINT32;
1550 return TYPECODE_INT32;
1552 return TYPECODE_UINT64;
1554 return TYPECODE_INT64;
1556 return TYPECODE_SINGLE;
1558 return TYPECODE_DOUBLE;
1559 case MONO_TYPE_VALUETYPE: {
1560 MonoClass *klass = type->data.klass;
1562 if (klass->enumtype) {
1563 t = mono_class_enum_basetype (klass)->type;
1565 } else if (mono_is_corlib_image (klass->image)) {
1566 if (strcmp (klass->name_space, "System") == 0) {
1567 if (strcmp (klass->name, "Decimal") == 0)
1568 return TYPECODE_DECIMAL;
1569 else if (strcmp (klass->name, "DateTime") == 0)
1570 return TYPECODE_DATETIME;
1573 return TYPECODE_OBJECT;
1575 case MONO_TYPE_STRING:
1576 return TYPECODE_STRING;
1577 case MONO_TYPE_SZARRAY:
1578 case MONO_TYPE_ARRAY:
1579 case MONO_TYPE_OBJECT:
1581 case MONO_TYPE_MVAR:
1582 case MONO_TYPE_TYPEDBYREF:
1583 return TYPECODE_OBJECT;
1584 case MONO_TYPE_CLASS:
1586 MonoClass *klass = type->data.klass;
1587 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1588 if (strcmp (klass->name, "DBNull") == 0)
1589 return TYPECODE_DBNULL;
1592 return TYPECODE_OBJECT;
1593 case MONO_TYPE_GENERICINST:
1594 return TYPECODE_OBJECT;
1596 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1602 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1604 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1605 return mono_class_enum_basetype (type->data.klass);
1606 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1607 return mono_class_enum_basetype (type->data.generic_class->container_class);
1611 ICALL_EXPORT guint32
1612 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_c, MonoError *error)
1614 mono_error_init (error);
1616 g_assert (!MONO_HANDLE_IS_NULL (ref_type));
1618 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1619 MonoClass *klass = mono_class_from_mono_type (type);
1620 MonoType *ctype = MONO_HANDLE_GETVAL (ref_c, type);
1621 MonoClass *klassc = mono_class_from_mono_type (ctype);
1623 if (type->byref ^ ctype->byref)
1627 MonoType *t = mono_type_get_underlying_type_ignore_byref (type);
1628 MonoType *ot = mono_type_get_underlying_type_ignore_byref (ctype);
1630 klass = mono_class_from_mono_type (t);
1631 klassc = mono_class_from_mono_type (ot);
1633 if (mono_type_is_primitive (t)) {
1634 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1635 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1636 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1637 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1638 return t->type == ot->type;
1640 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1643 if (klass->valuetype)
1644 return klass == klassc;
1645 return klass->valuetype == klassc->valuetype;
1648 return mono_class_is_assignable_from (klass, klassc);
1651 ICALL_EXPORT guint32
1652 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionTypeHandle ref_type, MonoObjectHandle obj, MonoError *error)
1654 mono_error_init (error);
1655 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1656 MonoClass *klass = mono_class_from_mono_type (type);
1657 mono_class_init_checked (klass, error);
1658 return_val_if_nok (error, FALSE);
1659 MonoObjectHandle inst = mono_object_handle_isinst (obj, klass, error);
1660 return_val_if_nok (error, FALSE);
1661 return !MONO_HANDLE_IS_NULL (inst);
1664 ICALL_EXPORT guint32
1665 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionTypeHandle ref_type, MonoError *error)
1667 mono_error_init (error);
1668 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
1669 MonoClass *klass = mono_class_from_mono_type (type);
1670 return mono_class_get_flags (klass);
1673 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1674 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h, MonoError *error)
1676 mono_error_init (error);
1677 MonoDomain *domain = MONO_HANDLE_DOMAIN (field_h);
1678 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1679 MonoClass *klass = field->parent;
1681 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1682 if (mono_class_is_gtd (klass) ||
1683 (gklass && gklass->context.class_inst->is_open))
1684 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1686 MonoType *ftype = mono_field_get_type (field);
1687 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1688 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1690 MonoMarshalType *info = mono_marshal_load_type_info (klass);
1692 for (int i = 0; i < info->num_fields; ++i) {
1693 if (info->fields [i].field == field) {
1694 if (!info->fields [i].mspec)
1695 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1697 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain, klass, info->fields [i].mspec, error);
1702 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1705 ICALL_EXPORT MonoReflectionFieldHandle
1706 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type, MonoError *error)
1712 mono_error_init (error);
1715 klass = handle->parent;
1717 klass = mono_class_from_mono_type (type);
1719 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1722 /* The managed code will throw the exception */
1723 return MONO_HANDLE_CAST (MonoReflectionField, NULL_HANDLE);
1726 return mono_field_get_object_handle (mono_domain_get (), klass, handle, error);
1729 ICALL_EXPORT MonoReflectionEventHandle
1730 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type, MonoError *error)
1736 mono_error_init (error);
1739 klass = handle->parent;
1741 klass = mono_class_from_mono_type (type);
1743 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1745 /* Managed code will throw an exception */
1746 return MONO_HANDLE_CAST (MonoReflectionEvent, NULL_HANDLE);
1749 return mono_event_get_object_handle (mono_domain_get (), klass, handle, error);
1753 ICALL_EXPORT MonoReflectionPropertyHandle
1754 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type, MonoError *error)
1756 mono_error_init (error);
1762 klass = handle->parent;
1764 klass = mono_class_from_mono_type (type);
1766 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1768 /* Managed code will throw an exception */
1769 return MONO_HANDLE_CAST (MonoReflectionProperty, NULL_HANDLE);
1772 return mono_property_get_object_handle (mono_domain_get (), klass, handle, error);
1775 ICALL_EXPORT MonoArrayHandle
1776 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
1778 mono_error_init (error);
1779 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1781 MonoType *type = mono_field_get_type_checked (field, error);
1783 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1785 return type_array_from_modifiers (field->parent->image, type, optional, error);
1789 vell_icall_get_method_attributes (MonoMethod *method)
1791 return method->flags;
1795 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1798 MonoReflectionType *rt;
1799 MonoDomain *domain = mono_domain_get ();
1800 MonoMethodSignature* sig;
1802 sig = mono_method_signature_checked (method, &error);
1803 if (!mono_error_ok (&error)) {
1804 mono_error_set_pending_exception (&error);
1808 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1809 if (!mono_error_ok (&error)) {
1810 mono_error_set_pending_exception (&error);
1814 MONO_STRUCT_SETREF (info, parent, rt);
1816 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1817 if (!mono_error_ok (&error)) {
1818 mono_error_set_pending_exception (&error);
1822 MONO_STRUCT_SETREF (info, ret, rt);
1824 info->attrs = method->flags;
1825 info->implattrs = method->iflags;
1826 if (sig->call_convention == MONO_CALL_DEFAULT)
1827 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1829 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1834 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1837 ICALL_EXPORT MonoArrayHandle
1838 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod *method, MonoReflectionMethodHandle member, MonoError *error)
1840 mono_error_init (error);
1841 MonoDomain *domain = mono_domain_get ();
1843 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1844 MONO_HANDLE_GET (reftype, member, reftype);
1845 MonoClass *klass = NULL;
1846 if (!MONO_HANDLE_IS_NULL (reftype))
1847 klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype, type));
1848 return mono_param_get_objects_internal (domain, method, klass, error);
1851 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1852 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method, MonoError *error)
1854 mono_error_init (error);
1855 MonoDomain *domain = mono_domain_get ();
1856 MonoReflectionMarshalAsAttributeHandle res = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
1858 MonoMarshalSpec **mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1859 mono_method_get_marshal_info (method, mspecs);
1862 MONO_HANDLE_ASSIGN (res, mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], error));
1868 for (int i = mono_method_signature (method)->param_count; i >= 0; i--)
1870 mono_metadata_free_marshal_spec (mspecs [i]);
1877 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1879 MonoClass *parent = field->field->parent;
1880 mono_class_setup_fields (parent);
1882 return field->field->offset - sizeof (MonoObject);
1885 ICALL_EXPORT MonoReflectionTypeHandle
1886 ves_icall_MonoField_GetParentType (MonoReflectionFieldHandle field, MonoBoolean declaring, MonoError *error)
1888 mono_error_init (error);
1889 MonoDomain *domain = MONO_HANDLE_DOMAIN (field);
1893 MonoClassField *f = MONO_HANDLE_GETVAL (field, field);
1896 parent = MONO_HANDLE_GETVAL (field, klass);
1899 return mono_type_get_object_handle (domain, &parent->byval_arg, error);
1902 ICALL_EXPORT MonoObject *
1903 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1906 MonoClass *fklass = field->klass;
1907 MonoClassField *cf = field->field;
1908 MonoDomain *domain = mono_object_domain (field);
1910 if (fklass->image->assembly->ref_only) {
1911 mono_set_pending_exception (mono_get_exception_invalid_operation (
1912 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1916 if (mono_security_core_clr_enabled () &&
1917 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1918 mono_error_set_pending_exception (&error);
1922 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1923 mono_error_set_pending_exception (&error);
1928 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1931 MonoClassField *cf = field->field;
1935 if (field->klass->image->assembly->ref_only) {
1936 mono_set_pending_exception (mono_get_exception_invalid_operation (
1937 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1941 if (mono_security_core_clr_enabled () &&
1942 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1943 mono_error_set_pending_exception (&error);
1947 type = mono_field_get_type_checked (cf, &error);
1948 if (!mono_error_ok (&error)) {
1949 mono_error_set_pending_exception (&error);
1953 v = (gchar *) value;
1955 switch (type->type) {
1958 case MONO_TYPE_BOOLEAN:
1961 case MONO_TYPE_CHAR:
1970 case MONO_TYPE_VALUETYPE:
1973 v += sizeof (MonoObject);
1975 case MONO_TYPE_STRING:
1976 case MONO_TYPE_OBJECT:
1977 case MONO_TYPE_CLASS:
1978 case MONO_TYPE_ARRAY:
1979 case MONO_TYPE_SZARRAY:
1982 case MONO_TYPE_GENERICINST: {
1983 MonoGenericClass *gclass = type->data.generic_class;
1984 g_assert (!gclass->context.class_inst->is_open);
1986 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1987 MonoClass *nklass = mono_class_from_mono_type (type);
1988 MonoObject *nullable;
1991 * Convert the boxed vtype into a Nullable structure.
1992 * This is complicated by the fact that Nullables have
1993 * a variable structure.
1995 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
1996 if (!mono_error_ok (&error)) {
1997 mono_error_set_pending_exception (&error);
2001 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2003 v = (gchar *)mono_object_unbox (nullable);
2006 if (gclass->container_class->valuetype && (v != NULL))
2007 v += sizeof (MonoObject);
2011 g_error ("type 0x%x not handled in "
2012 "ves_icall_FieldInfo_SetValueInternal", type->type);
2017 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2018 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2019 if (!is_ok (&error)) {
2020 mono_error_set_pending_exception (&error);
2023 if (!vtable->initialized) {
2024 if (!mono_runtime_class_init_full (vtable, &error)) {
2025 mono_error_set_pending_exception (&error);
2029 mono_field_static_set_value (vtable, cf, v);
2031 mono_field_set_value (obj, cf, v);
2036 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2045 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2046 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2050 if (MONO_TYPE_IS_REFERENCE (f->type))
2051 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2053 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2056 ICALL_EXPORT MonoObject *
2057 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2059 MonoObject *o = NULL;
2060 MonoClassField *field = rfield->field;
2062 MonoDomain *domain = mono_object_domain (rfield);
2064 MonoTypeEnum def_type;
2065 const char *def_value;
2069 mono_class_init (field->parent);
2071 t = mono_field_get_type_checked (field, &error);
2072 if (!mono_error_ok (&error)) {
2073 mono_error_set_pending_exception (&error);
2077 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2078 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2082 if (image_is_dynamic (field->parent->image)) {
2083 MonoClass *klass = field->parent;
2084 int fidx = field - klass->fields;
2085 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2087 g_assert (def_values);
2088 def_type = def_values [fidx].def_type;
2089 def_value = def_values [fidx].data;
2091 if (def_type == MONO_TYPE_END) {
2092 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2096 def_value = mono_class_get_field_default_value (field, &def_type);
2097 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2099 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2104 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2108 case MONO_TYPE_BOOLEAN:
2111 case MONO_TYPE_CHAR:
2119 case MONO_TYPE_R8: {
2122 /* boxed value type */
2123 t = g_new0 (MonoType, 1);
2125 klass = mono_class_from_mono_type (t);
2127 o = mono_object_new_checked (domain, klass, &error);
2128 if (!mono_error_ok (&error)) {
2129 mono_error_set_pending_exception (&error);
2132 v = ((gchar *) o) + sizeof (MonoObject);
2133 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2134 if (mono_error_set_pending_exception (&error))
2138 case MONO_TYPE_STRING:
2139 case MONO_TYPE_CLASS:
2140 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2141 if (mono_error_set_pending_exception (&error))
2145 g_assert_not_reached ();
2151 ICALL_EXPORT MonoReflectionTypeHandle
2152 ves_icall_MonoField_ResolveType (MonoReflectionFieldHandle ref_field, MonoError *error)
2154 mono_error_init (error);
2155 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_field);
2156 MonoClassField *field = MONO_HANDLE_GETVAL (ref_field, field);
2157 MonoType *type = mono_field_get_type_checked (field, error);
2158 if (!is_ok (error)) {
2159 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2161 return mono_type_get_object_handle (domain, type, error);
2164 /* From MonoProperty.cs */
2166 PInfo_Attributes = 1,
2167 PInfo_GetMethod = 1 << 1,
2168 PInfo_SetMethod = 1 << 2,
2169 PInfo_ReflectedType = 1 << 3,
2170 PInfo_DeclaringType = 1 << 4,
2175 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2178 MonoReflectionType *rt;
2179 MonoReflectionMethod *rm;
2180 MonoDomain *domain = mono_object_domain (property);
2181 const MonoProperty *pproperty = property->property;
2183 if ((req_info & PInfo_ReflectedType) != 0) {
2184 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2185 if (mono_error_set_pending_exception (&error))
2188 MONO_STRUCT_SETREF (info, parent, rt);
2190 if ((req_info & PInfo_DeclaringType) != 0) {
2191 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2192 if (mono_error_set_pending_exception (&error))
2195 MONO_STRUCT_SETREF (info, declaring_type, rt);
2198 if ((req_info & PInfo_Name) != 0)
2199 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2201 if ((req_info & PInfo_Attributes) != 0)
2202 info->attrs = pproperty->attrs;
2204 if ((req_info & PInfo_GetMethod) != 0) {
2205 if (pproperty->get &&
2206 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2207 pproperty->get->klass == property->klass)) {
2208 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2209 if (mono_error_set_pending_exception (&error))
2215 MONO_STRUCT_SETREF (info, get, rm);
2217 if ((req_info & PInfo_SetMethod) != 0) {
2218 if (pproperty->set &&
2219 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2220 pproperty->set->klass == property->klass)) {
2221 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2222 if (mono_error_set_pending_exception (&error))
2228 MONO_STRUCT_SETREF (info, set, rm);
2231 * There may be other methods defined for properties, though, it seems they are not exposed
2232 * in the reflection API
2237 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2240 MonoReflectionType *rt;
2241 MonoReflectionMethod *rm;
2242 MonoDomain *domain = mono_object_domain (event);
2244 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2245 if (mono_error_set_pending_exception (&error))
2248 MONO_STRUCT_SETREF (info, reflected_type, rt);
2250 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2251 if (mono_error_set_pending_exception (&error))
2254 MONO_STRUCT_SETREF (info, declaring_type, rt);
2256 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2257 info->attrs = event->event->attrs;
2259 if (event->event->add) {
2260 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2261 if (mono_error_set_pending_exception (&error))
2267 MONO_STRUCT_SETREF (info, add_method, rm);
2269 if (event->event->remove) {
2270 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2271 if (mono_error_set_pending_exception (&error))
2277 MONO_STRUCT_SETREF (info, remove_method, rm);
2279 if (event->event->raise) {
2280 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2281 if (mono_error_set_pending_exception (&error))
2287 MONO_STRUCT_SETREF (info, raise_method, rm);
2289 #ifndef MONO_SMALL_CONFIG
2290 if (event->event->other) {
2292 while (event->event->other [n])
2294 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2295 if (mono_error_set_pending_exception (&error))
2297 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2299 for (i = 0; i < n; i++) {
2300 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2301 if (mono_error_set_pending_exception (&error))
2303 mono_array_setref (info->other_methods, i, rm);
2310 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2315 mono_class_setup_interfaces (klass, error);
2316 if (!mono_error_ok (error))
2319 for (i = 0; i < klass->interface_count; i++) {
2320 ic = klass->interfaces [i];
2321 g_hash_table_insert (ifaces, ic, ic);
2323 collect_interfaces (ic, ifaces, error);
2324 if (!mono_error_ok (error))
2330 MonoArrayHandle iface_array;
2331 MonoGenericContext *context;
2335 } FillIfaceArrayData;
2338 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2340 HANDLE_FUNCTION_ENTER ();
2341 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2342 MonoClass *ic = (MonoClass *)key;
2343 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2344 MonoError *error = data->error;
2349 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2350 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, error);
2355 MonoReflectionTypeHandle rt = mono_type_get_object_handle (data->domain, ret, error);
2359 MONO_HANDLE_ARRAY_SETREF (data->iface_array, data->next_idx, rt);
2363 mono_metadata_free_type (inflated);
2365 HANDLE_FUNCTION_RETURN ();
2369 get_interfaces_hash (gconstpointer v1)
2371 MonoClass *k = (MonoClass*)v1;
2373 return k->type_token;
2376 ICALL_EXPORT MonoArrayHandle
2377 ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type, MonoError *error)
2379 mono_error_init (error);
2380 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2381 MonoClass *klass = mono_class_from_mono_type (type);
2383 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2385 MonoGenericContext *context = NULL;
2386 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2387 context = mono_class_get_context (klass);
2388 klass = mono_class_get_generic_class (klass)->container_class;
2391 for (MonoClass *parent = klass; parent; parent = parent->parent) {
2392 mono_class_setup_interfaces (parent, error);
2395 collect_interfaces (parent, iface_hash, error);
2400 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2402 int len = g_hash_table_size (iface_hash);
2404 g_hash_table_destroy (iface_hash);
2405 if (!domain->empty_types) {
2406 domain->empty_types = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, error);
2410 return MONO_HANDLE_NEW (MonoArray, domain->empty_types);
2413 FillIfaceArrayData data;
2414 data.iface_array = MONO_HANDLE_NEW (MonoArray, mono_array_new_cached (domain, mono_defaults.runtimetype_class, len, error));
2417 data.context = context;
2419 data.domain = domain;
2422 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2427 g_hash_table_destroy (iface_hash);
2428 return data.iface_array;
2431 g_hash_table_destroy (iface_hash);
2432 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
2436 set_interface_map_data_method_object (MonoDomain *domain, MonoMethod *method, MonoClass *iclass, int ioffset, MonoClass *klass, MonoArrayHandle targets, MonoArrayHandle methods, int i, MonoError *error)
2438 HANDLE_FUNCTION_ENTER ();
2439 mono_error_init (error);
2440 MonoReflectionMethodHandle member = mono_method_get_object_handle (domain, method, iclass, error);
2444 MONO_HANDLE_ARRAY_SETREF (methods, i, member);
2446 MONO_HANDLE_ASSIGN (member, mono_method_get_object_handle (domain, klass->vtable [i + ioffset], klass, error));
2450 MONO_HANDLE_ARRAY_SETREF (targets, i, member);
2453 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2457 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionTypeHandle ref_type, MonoReflectionTypeHandle ref_iface, MonoArrayHandleOut targets, MonoArrayHandleOut methods, MonoError *error)
2459 mono_error_init (error);
2460 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2461 MonoClass *klass = mono_class_from_mono_type (type);
2462 MonoType *iface = MONO_HANDLE_GETVAL (ref_iface, type);
2463 MonoClass *iclass = mono_class_from_mono_type (iface);
2465 mono_class_init_checked (klass, error);
2466 return_if_nok (error);
2467 mono_class_init_checked (iclass, error);
2468 return_if_nok (error);
2470 mono_class_setup_vtable (klass);
2472 gboolean variance_used;
2473 int ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2477 int len = mono_class_num_methods (iclass);
2478 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2479 MonoArrayHandle targets_arr = mono_array_new_handle (domain, mono_defaults.method_info_class, len, error);
2480 return_if_nok (error);
2481 MONO_HANDLE_ASSIGN (targets, targets_arr);
2483 MonoArrayHandle methods_arr = mono_array_new_handle (domain, mono_defaults.method_info_class, len, error);
2484 return_if_nok (error);
2485 MONO_HANDLE_ASSIGN (methods, methods_arr);
2489 gpointer iter = NULL;
2490 while ((method = mono_class_get_methods (iclass, &iter))) {
2491 if (!set_interface_map_data_method_object (domain, method, iclass, ioffset, klass, targets, methods, i, error))
2498 ves_icall_RuntimeType_GetPacking (MonoReflectionTypeHandle ref_type, guint32 *packing, guint32 *size, MonoError *error)
2500 mono_error_init (error);
2501 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2502 MonoClass *klass = mono_class_from_mono_type (type);
2504 mono_class_init_checked (klass, error);
2508 if (image_is_dynamic (klass->image)) {
2509 MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_type);
2510 *packing = MONO_HANDLE_GETVAL (tb, packing_size);
2511 *size = MONO_HANDLE_GETVAL (tb, class_size);
2513 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2517 ICALL_EXPORT MonoReflectionTypeHandle
2518 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionTypeHandle ref_type, MonoError *error)
2520 mono_error_init (error);
2522 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2523 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2525 if (!type->byref && type->type == MONO_TYPE_SZARRAY) {
2526 return mono_type_get_object_handle (domain, &type->data.klass->byval_arg, error);
2529 MonoClass *klass = mono_class_from_mono_type (type);
2530 mono_class_init_checked (klass, error);
2532 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2534 // GetElementType should only return a type for:
2535 // Array Pointer PassedByRef
2537 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2538 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2539 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2540 else if (klass->element_class && type->type == MONO_TYPE_PTR)
2541 return mono_type_get_object_handle (domain, &klass->element_class->byval_arg, error);
2543 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2546 ICALL_EXPORT MonoReflectionTypeHandle
2547 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionTypeHandle ref_type, MonoError *error)
2549 mono_error_init (error);
2551 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2552 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2555 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2557 MonoClass *klass = mono_class_from_mono_type (type);
2559 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2561 return mono_type_get_object_handle (domain, &klass->parent->byval_arg, error);
2564 ICALL_EXPORT MonoBoolean
2565 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionTypeHandle ref_type, MonoError *error)
2567 mono_error_init (error);
2568 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2569 return type->type == MONO_TYPE_PTR;
2572 ICALL_EXPORT MonoBoolean
2573 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type, MonoError *error)
2575 mono_error_init (error);
2576 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2577 return (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)));
2580 ICALL_EXPORT MonoBoolean
2581 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type, MonoError *error)
2583 mono_error_init (error);
2584 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2588 ICALL_EXPORT MonoBoolean
2589 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionTypeHandle ref_type, MonoError *error)
2591 mono_error_init (error);
2592 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2593 MonoClass *klass = mono_class_from_mono_type (type);
2594 mono_class_init_checked (klass, error);
2598 return mono_class_is_com_object (klass);
2601 ICALL_EXPORT guint32
2602 ves_icall_reflection_get_token (MonoObjectHandle obj, MonoError *error)
2604 mono_error_init (error);
2605 return mono_reflection_get_token_checked (obj, error);
2608 ICALL_EXPORT MonoReflectionModuleHandle
2609 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2611 mono_error_init (error);
2612 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2613 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2614 MonoClass *klass = mono_class_from_mono_type (t);
2615 return mono_module_get_object_handle (domain, klass->image, error);
2618 ICALL_EXPORT MonoReflectionAssemblyHandle
2619 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2621 mono_error_init (error);
2622 MonoDomain *domain = mono_domain_get ();
2623 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2624 MonoClass *klass = mono_class_from_mono_type (t);
2625 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2628 ICALL_EXPORT MonoReflectionTypeHandle
2629 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionTypeHandle ref_type, MonoError *error)
2631 mono_error_init (error);
2632 MonoDomain *domain = mono_domain_get ();
2633 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2637 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2638 if (type->type == MONO_TYPE_VAR) {
2639 MonoGenericContainer *param = mono_type_get_generic_param_owner (type);
2640 klass = param ? param->owner.klass : NULL;
2641 } else if (type->type == MONO_TYPE_MVAR) {
2642 MonoGenericContainer *param = mono_type_get_generic_param_owner (type);
2643 klass = param ? param->owner.method->klass : NULL;
2645 klass = mono_class_from_mono_type (type)->nested_in;
2649 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
2651 return mono_type_get_object_handle (domain, &klass->byval_arg, error);
2654 ICALL_EXPORT MonoStringHandle
2655 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2657 MonoDomain *domain = mono_domain_get ();
2658 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2659 MonoClass *klass = mono_class_from_mono_type (type);
2662 char *n = g_strdup_printf ("%s&", klass->name);
2663 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2669 return mono_string_new_handle (domain, klass->name, error);
2673 ICALL_EXPORT MonoStringHandle
2674 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2676 MonoDomain *domain = mono_domain_get ();
2677 MonoClass *klass = mono_class_from_mono_type_handle (type);
2679 while (klass->nested_in)
2680 klass = klass->nested_in;
2682 if (klass->name_space [0] == '\0')
2683 return NULL_HANDLE_STRING;
2685 return mono_string_new_handle (domain, klass->name_space, error);
2689 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionTypeHandle ref_type, MonoError *error)
2691 mono_error_init (error);
2692 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2694 if (type->type != MONO_TYPE_ARRAY && type->type != MONO_TYPE_SZARRAY) {
2695 mono_error_set_argument (error, "type", "Type must be an array type");
2699 MonoClass *klass = mono_class_from_mono_type (type);
2704 static MonoArrayHandle
2705 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2707 return mono_array_new_handle (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2711 set_type_object_in_array (MonoDomain *domain, MonoType *type, MonoArrayHandle dest, int i, MonoError *error)
2713 HANDLE_FUNCTION_ENTER();
2714 mono_error_init (error);
2715 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, type, error);
2719 MONO_HANDLE_ARRAY_SETREF (dest, i, rt);
2722 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
2725 ICALL_EXPORT MonoArrayHandle
2726 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionTypeHandle ref_type, MonoBoolean runtimeTypeArray, MonoError *error)
2728 mono_error_init (error);
2729 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2731 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2732 MonoClass *klass = mono_class_from_mono_type (type);
2734 MonoArrayHandle res = MONO_HANDLE_NEW (MonoArray, NULL);
2735 if (mono_class_is_gtd (klass)) {
2736 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2737 MONO_HANDLE_ASSIGN (res, create_type_array (domain, runtimeTypeArray, container->type_argc, error));
2740 for (int i = 0; i < container->type_argc; ++i) {
2741 MonoClass *pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2743 if (!set_type_object_in_array (domain, &pklass->byval_arg, res, i, error))
2747 } else if (mono_class_is_ginst (klass)) {
2748 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2749 MONO_HANDLE_ASSIGN (res, create_type_array (domain, runtimeTypeArray, inst->type_argc, error));
2752 for (int i = 0; i < inst->type_argc; ++i) {
2753 if (!set_type_object_in_array (domain, inst->type_argv [i], res, i, error))
2762 ICALL_EXPORT gboolean
2763 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionTypeHandle ref_type, MonoError *error)
2765 mono_error_init (error);
2767 if (!IS_MONOTYPE (MONO_HANDLE_RAW(ref_type)))
2770 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2774 MonoClass *klass = mono_class_from_mono_type (type);
2775 return mono_class_is_gtd (klass);
2778 ICALL_EXPORT MonoReflectionTypeHandle
2779 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionTypeHandle ref_type, MonoError *error)
2781 mono_error_init (error);
2782 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2784 MonoReflectionTypeHandle ret = MONO_HANDLE_NEW (MonoReflectionType, NULL);
2789 MonoClass *klass = mono_class_from_mono_type (type);
2791 if (mono_class_is_gtd (klass)) {
2792 /* check this one */
2793 MONO_HANDLE_ASSIGN (ret, ref_type);
2796 if (mono_class_is_ginst (klass)) {
2797 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2799 guint32 ref_info_handle = mono_class_get_ref_info_handle (generic_class);
2801 if (generic_class->wastypebuilder && ref_info_handle) {
2802 MonoObjectHandle tb = mono_gchandle_get_target_handle (ref_info_handle);
2803 g_assert (!MONO_HANDLE_IS_NULL (tb));
2804 MONO_HANDLE_ASSIGN (ret, tb);
2806 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2807 MONO_HANDLE_ASSIGN (ret, mono_type_get_object_handle (domain, &generic_class->byval_arg, error));
2814 ICALL_EXPORT MonoReflectionType*
2815 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2818 MonoReflectionType *ret;
2820 MonoType *geninst, **types;
2823 g_assert (IS_MONOTYPE (type));
2824 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2825 if (mono_error_set_pending_exception (&error))
2828 count = mono_array_length (type_array);
2829 types = g_new0 (MonoType *, count);
2831 for (i = 0; i < count; i++) {
2832 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2833 types [i] = t->type;
2836 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2839 mono_error_set_pending_exception (&error);
2843 klass = mono_class_from_mono_type (geninst);
2845 /*we might inflate to the GTD*/
2846 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2847 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2851 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2852 mono_error_set_pending_exception (&error);
2857 ICALL_EXPORT gboolean
2858 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionTypeHandle ref_type, MonoError *error)
2860 mono_error_init (error);
2863 if (!IS_MONOTYPE (MONO_HANDLE_RAW (ref_type)))
2866 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2870 klass = mono_class_from_mono_type (type);
2871 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2875 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionTypeHandle ref_type, MonoError *error)
2877 mono_error_init (error);
2878 if (!IS_MONOTYPE_HANDLE (ref_type))
2880 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2882 if (is_generic_parameter (type))
2883 return mono_type_get_generic_param_num (type);
2887 ICALL_EXPORT MonoGenericParamInfo *
2888 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionTypeHandle ref_type, MonoError *error)
2890 mono_error_init (error);
2891 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2892 return mono_generic_param_info (type->data.generic_param);
2895 ICALL_EXPORT MonoBoolean
2896 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionTypeHandle ref_type, MonoError *error)
2898 MonoType *type = MONO_HANDLE_GETVAL(ref_type, type);
2899 return is_generic_parameter (type);
2902 ICALL_EXPORT MonoReflectionMethodHandle
2903 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionTypeHandle ref_type,
2904 MonoReflectionMethodHandle generic,
2907 mono_error_init (error);
2908 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2909 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2910 MonoClass *klass = mono_class_from_mono_type (type);
2912 mono_class_init_checked (klass, error);
2914 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2916 MonoMethod *generic_method = MONO_HANDLE_GETVAL (generic, method);
2918 MonoReflectionMethodHandle ret = MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2920 gpointer iter = NULL;
2921 while ((method = mono_class_get_methods (klass, &iter))) {
2922 if (method->token == generic_method->token) {
2923 ret = mono_method_get_object_handle (domain, method, klass, error);
2925 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
2932 ICALL_EXPORT MonoReflectionMethodHandle
2933 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionTypeHandle ref_type, MonoError *error)
2935 mono_error_init (error);
2936 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
2937 MonoReflectionMethodHandle ret = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
2939 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2940 mono_error_set_invalid_operation (error, "DeclaringMethod can only be used on generic arguments");
2943 if (type->type == MONO_TYPE_VAR)
2946 MonoMethod *method = mono_type_get_generic_param_owner (type)->owner.method;
2949 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
2951 MONO_HANDLE_ASSIGN (ret, mono_method_get_object_handle (domain, method, method->klass, error));
2956 ICALL_EXPORT MonoBoolean
2957 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (MonoError *error)
2959 mono_error_init (error);
2960 mono_error_set_not_implemented (error, "%s", "");
2964 ICALL_EXPORT MonoBoolean
2965 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (MonoError *error)
2967 mono_error_init (error);
2968 mono_error_set_not_implemented (error, "%s", "");
2973 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2975 MonoDomain *domain = mono_domain_get ();
2976 MonoImage *image = method->method->klass->image;
2977 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2978 MonoTableInfo *tables = image->tables;
2979 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2980 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2981 guint32 im_cols [MONO_IMPLMAP_SIZE];
2982 guint32 scope_token;
2983 const char *import = NULL;
2984 const char *scope = NULL;
2986 if (image_is_dynamic (image)) {
2987 MonoReflectionMethodAux *method_aux =
2988 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2990 import = method_aux->dllentry;
2991 scope = method_aux->dll;
2994 if (!import || !scope) {
2995 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
3000 if (piinfo->implmap_idx) {
3001 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
3003 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
3004 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
3005 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
3006 scope = mono_metadata_string_heap (image, scope_token);
3010 *flags = piinfo->piflags;
3011 *entry_point = mono_string_new (domain, import);
3012 *dll_name = mono_string_new (domain, scope);
3015 ICALL_EXPORT MonoReflectionMethod *
3016 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3018 MonoMethodInflated *imethod;
3020 MonoReflectionMethod *ret = NULL;
3023 if (method->method->is_generic)
3026 if (!method->method->is_inflated)
3029 imethod = (MonoMethodInflated *) method->method;
3031 result = imethod->declaring;
3032 /* Not a generic method. */
3033 if (!result->is_generic)
3036 if (image_is_dynamic (method->method->klass->image)) {
3037 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3038 MonoReflectionMethod *res;
3041 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3042 * the dynamic case as well ?
3044 mono_image_lock ((MonoImage*)image);
3045 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3046 mono_image_unlock ((MonoImage*)image);
3052 if (imethod->context.class_inst) {
3053 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3054 /*Generic methods gets the context of the GTD.*/
3055 if (mono_class_get_context (klass)) {
3056 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3057 if (!mono_error_ok (&error))
3062 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3064 if (!mono_error_ok (&error))
3065 mono_error_set_pending_exception (&error);
3069 ICALL_EXPORT gboolean
3070 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3072 return mono_method_signature (method->method)->generic_param_count != 0;
3075 ICALL_EXPORT gboolean
3076 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3078 return method->method->is_generic;
3081 ICALL_EXPORT MonoArray*
3082 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3085 MonoReflectionType *rt;
3090 domain = mono_object_domain (method);
3092 if (method->method->is_inflated) {
3093 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3096 count = inst->type_argc;
3097 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3098 if (mono_error_set_pending_exception (&error))
3101 for (i = 0; i < count; i++) {
3102 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3103 if (mono_error_set_pending_exception (&error))
3106 mono_array_setref (res, i, rt);
3113 count = mono_method_signature (method->method)->generic_param_count;
3114 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3115 if (mono_error_set_pending_exception (&error))
3118 for (i = 0; i < count; i++) {
3119 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3120 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3121 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3123 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3124 if (mono_error_set_pending_exception (&error))
3127 mono_array_setref (res, i, rt);
3133 ICALL_EXPORT MonoObject *
3134 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3138 * Invoke from reflection is supposed to always be a virtual call (the API
3139 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3140 * greater flexibility.
3142 MonoMethod *m = method->method;
3143 MonoMethodSignature *sig = mono_method_signature (m);
3146 void *obj = this_arg;
3150 if (mono_security_core_clr_enabled () &&
3151 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3152 mono_error_set_pending_exception (&error);
3156 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3157 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3158 mono_error_cleanup (&error); /* FIXME does this make sense? */
3159 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3164 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3165 if (!is_ok (&error)) {
3166 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3169 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3170 char *target_name = mono_type_get_full_name (m->klass);
3171 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3172 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3174 g_free (target_name);
3178 m = mono_object_get_virtual_method (this_arg, m);
3179 /* must pass the pointer to the value for valuetype methods */
3180 if (m->klass->valuetype)
3181 obj = mono_object_unbox (this_arg);
3182 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3183 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3188 if (sig->ret->byref) {
3189 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"));
3193 pcount = params? mono_array_length (params): 0;
3194 if (pcount != sig->param_count) {
3195 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3199 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3200 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."));
3204 image = m->klass->image;
3205 if (image->assembly->ref_only) {
3206 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."));
3210 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3211 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3215 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3219 intptr_t *lower_bounds;
3220 pcount = mono_array_length (params);
3221 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3222 /* Note: the synthetized array .ctors have int32 as argument type */
3223 for (i = 0; i < pcount; ++i)
3224 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3226 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3227 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3228 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3229 if (!mono_error_ok (&error)) {
3230 mono_error_set_pending_exception (&error);
3234 for (i = 0; i < mono_array_length (arr); ++i) {
3235 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3236 if (!mono_error_ok (&error)) {
3237 mono_error_set_pending_exception (&error);
3240 mono_array_setref_fast (arr, i, subarray);
3242 return (MonoObject*)arr;
3245 if (m->klass->rank == pcount) {
3246 /* Only lengths provided. */
3247 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3248 if (!mono_error_ok (&error)) {
3249 mono_error_set_pending_exception (&error);
3253 return (MonoObject*)arr;
3255 g_assert (pcount == (m->klass->rank * 2));
3256 /* The arguments are lower-bound-length pairs */
3257 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3259 for (i = 0; i < pcount / 2; ++i) {
3260 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3261 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3264 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3265 if (!mono_error_ok (&error)) {
3266 mono_error_set_pending_exception (&error);
3270 return (MonoObject*)arr;
3273 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3274 mono_error_set_pending_exception (&error);
3278 #ifndef DISABLE_REMOTING
3279 ICALL_EXPORT MonoObject *
3280 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3283 MonoDomain *domain = mono_object_domain (method);
3284 MonoMethod *m = method->method;
3285 MonoMethodSignature *sig = mono_method_signature (m);
3286 MonoArray *out_args;
3288 int i, j, outarg_count = 0;
3290 if (m->klass == mono_defaults.object_class) {
3291 if (!strcmp (m->name, "FieldGetter")) {
3292 MonoClass *k = mono_object_class (this_arg);
3296 /* If this is a proxy, then it must be a CBO */
3297 if (mono_class_is_transparent_proxy (k)) {
3298 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3299 this_arg = tp->rp->unwrapped_server;
3300 g_assert (this_arg);
3301 k = mono_object_class (this_arg);
3304 name = mono_array_get (params, MonoString *, 1);
3305 str = mono_string_to_utf8_checked (name, &error);
3306 if (mono_error_set_pending_exception (&error))
3310 MonoClassField* field = mono_class_get_field_from_name (k, str);
3313 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3314 if (field_klass->valuetype) {
3315 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3316 if (mono_error_set_pending_exception (&error))
3319 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3321 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3322 if (mono_error_set_pending_exception (&error))
3324 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3325 mono_array_setref (out_args, 0, result);
3332 g_assert_not_reached ();
3334 } else if (!strcmp (m->name, "FieldSetter")) {
3335 MonoClass *k = mono_object_class (this_arg);
3341 /* If this is a proxy, then it must be a CBO */
3342 if (mono_class_is_transparent_proxy (k)) {
3343 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3344 this_arg = tp->rp->unwrapped_server;
3345 g_assert (this_arg);
3346 k = mono_object_class (this_arg);
3349 name = mono_array_get (params, MonoString *, 1);
3350 str = mono_string_to_utf8_checked (name, &error);
3351 if (mono_error_set_pending_exception (&error))
3355 MonoClassField* field = mono_class_get_field_from_name (k, str);
3358 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3359 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3361 if (field_klass->valuetype) {
3362 size = mono_type_size (field->type, &align);
3363 g_assert (size == mono_class_value_size (field_klass, NULL));
3364 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3366 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3369 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3370 if (mono_error_set_pending_exception (&error))
3372 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3381 g_assert_not_reached ();
3386 for (i = 0; i < mono_array_length (params); i++) {
3387 if (sig->params [i]->byref)
3391 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3392 if (mono_error_set_pending_exception (&error))
3395 /* handle constructors only for objects already allocated */
3396 if (!strcmp (method->method->name, ".ctor"))
3397 g_assert (this_arg);
3399 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3400 g_assert (!method->method->klass->valuetype);
3401 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3402 if (mono_error_set_pending_exception (&error))
3405 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3406 if (sig->params [i]->byref) {
3408 arg = mono_array_get (params, gpointer, i);
3409 mono_array_setref (out_args, j, arg);
3414 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3421 read_enum_value (const char *mem, int type)
3424 case MONO_TYPE_BOOLEAN:
3426 return *(guint8*)mem;
3428 return *(gint8*)mem;
3429 case MONO_TYPE_CHAR:
3431 return read16 (mem);
3433 return (gint16) read16 (mem);
3435 return read32 (mem);
3437 return (gint32) read32 (mem);
3440 return read64 (mem);
3442 g_assert_not_reached ();
3448 write_enum_value (char *mem, int type, guint64 value)
3452 case MONO_TYPE_I1: {
3453 guint8 *p = (guint8*)mem;
3459 case MONO_TYPE_CHAR: {
3460 guint16 *p = (guint16 *)mem;
3465 case MONO_TYPE_I4: {
3466 guint32 *p = (guint32 *)mem;
3471 case MONO_TYPE_I8: {
3472 guint64 *p = (guint64 *)mem;
3477 g_assert_not_reached ();
3482 ICALL_EXPORT MonoObject *
3483 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3491 domain = mono_object_domain (enumType);
3492 enumc = mono_class_from_mono_type (enumType->type);
3494 mono_class_init_checked (enumc, &error);
3495 if (mono_error_set_pending_exception (&error))
3498 etype = mono_class_enum_basetype (enumc);
3500 res = mono_object_new_checked (domain, enumc, &error);
3501 if (mono_error_set_pending_exception (&error))
3503 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3508 ICALL_EXPORT MonoBoolean
3509 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3511 int size = mono_class_value_size (a->vtable->klass, NULL);
3512 guint64 a_val = 0, b_val = 0;
3514 memcpy (&a_val, mono_object_unbox (a), size);
3515 memcpy (&b_val, mono_object_unbox (b), size);
3517 return (a_val & b_val) == b_val;
3520 ICALL_EXPORT MonoObject *
3521 ves_icall_System_Enum_get_value (MonoObject *eobj)
3533 g_assert (eobj->vtable->klass->enumtype);
3535 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3536 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3537 if (mono_error_set_pending_exception (&error))
3539 dst = (char *)res + sizeof (MonoObject);
3540 src = (char *)eobj + sizeof (MonoObject);
3541 size = mono_class_value_size (enumc, NULL);
3543 memcpy (dst, src, size);
3548 ICALL_EXPORT MonoReflectionType *
3549 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3552 MonoReflectionType *ret;
3556 klass = mono_class_from_mono_type (type->type);
3557 mono_class_init_checked (klass, &error);
3558 if (mono_error_set_pending_exception (&error))
3561 etype = mono_class_enum_basetype (klass);
3563 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3567 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3568 mono_error_set_pending_exception (&error);
3574 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3576 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3577 gpointer odata = (char *)other + sizeof (MonoObject);
3578 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3579 g_assert (basetype);
3584 if (eobj->vtable->klass != other->vtable->klass)
3587 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3588 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3589 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3592 return me > other ? 1 : -1; \
3595 switch (basetype->type) {
3597 COMPARE_ENUM_VALUES (guint8);
3599 COMPARE_ENUM_VALUES (gint8);
3600 case MONO_TYPE_CHAR:
3602 COMPARE_ENUM_VALUES (guint16);
3604 COMPARE_ENUM_VALUES (gint16);
3606 COMPARE_ENUM_VALUES (guint32);
3608 COMPARE_ENUM_VALUES (gint32);
3610 COMPARE_ENUM_VALUES (guint64);
3612 COMPARE_ENUM_VALUES (gint64);
3616 #undef COMPARE_ENUM_VALUES
3617 /* indicates that the enum was of an unsupported unerlying type */
3622 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3624 gpointer data = (char *)eobj + sizeof (MonoObject);
3625 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3626 g_assert (basetype);
3628 switch (basetype->type) {
3629 case MONO_TYPE_I1: {
3630 gint8 value = *((gint8*)data);
3631 return ((int)value ^ (int)value << 8);
3634 return *((guint8*)data);
3635 case MONO_TYPE_CHAR:
3637 return *((guint16*)data);
3639 case MONO_TYPE_I2: {
3640 gint16 value = *((gint16*)data);
3641 return ((int)(guint16)value | (((int)value) << 16));
3644 return *((guint32*)data);
3646 return *((gint32*)data);
3648 case MONO_TYPE_I8: {
3649 gint64 value = *((gint64*)data);
3650 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3653 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3659 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3661 mono_error_init (error);
3662 HANDLE_FUNCTION_ENTER();
3663 guint64 field_value;
3665 MonoTypeEnum def_type;
3667 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3669 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3671 if (mono_field_is_deleted (field))
3673 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3676 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3678 p = mono_class_get_field_default_value (field, &def_type);
3679 /* len = */ mono_metadata_decode_blob_size (p, &p);
3681 field_value = read_enum_value (p, base_type);
3682 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3684 if (*previous_value > field_value)
3687 *previous_value = field_value;
3690 HANDLE_FUNCTION_RETURN();
3693 ICALL_EXPORT MonoBoolean
3694 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3696 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3697 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3698 guint j = 0, nvalues;
3700 MonoClassField *field;
3702 guint64 previous_value = 0;
3703 gboolean sorted = TRUE;
3705 mono_error_init (error);
3706 mono_class_init_checked (enumc, error);
3707 return_val_if_nok (error, FALSE);
3709 if (!enumc->enumtype) {
3710 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3714 base_type = mono_class_enum_basetype (enumc)->type;
3716 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3717 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3718 return_val_if_nok (error, FALSE);
3719 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3720 return_val_if_nok (error, FALSE);
3723 while ((field = mono_class_get_fields (enumc, &iter))) {
3724 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3728 return_val_if_nok (error, FALSE);
3734 BFLAGS_IgnoreCase = 1,
3735 BFLAGS_DeclaredOnly = 2,
3736 BFLAGS_Instance = 4,
3738 BFLAGS_Public = 0x10,
3739 BFLAGS_NonPublic = 0x20,
3740 BFLAGS_FlattenHierarchy = 0x40,
3741 BFLAGS_InvokeMethod = 0x100,
3742 BFLAGS_CreateInstance = 0x200,
3743 BFLAGS_GetField = 0x400,
3744 BFLAGS_SetField = 0x800,
3745 BFLAGS_GetProperty = 0x1000,
3746 BFLAGS_SetProperty = 0x2000,
3747 BFLAGS_ExactBinding = 0x10000,
3748 BFLAGS_SuppressChangeType = 0x20000,
3749 BFLAGS_OptionalParamBinding = 0x40000
3752 ICALL_EXPORT GPtrArray*
3753 ves_icall_RuntimeType_GetFields_native (MonoReflectionTypeHandle ref_type, char *utf8_name, guint32 bflags, MonoError *error)
3755 mono_error_init (error);
3756 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3759 return g_ptr_array_new ();
3762 int (*compare_func) (const char *s1, const char *s2) = NULL;
3763 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3765 MonoClass *startklass, *klass;
3766 klass = startklass = mono_class_from_mono_type (type);
3768 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3771 if (mono_class_has_failure (klass)) {
3772 mono_error_set_for_class_failure (error, klass);
3776 MonoClassField *field;
3777 gpointer iter = NULL;
3778 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3779 guint32 flags = mono_field_get_flags (field);
3781 if (mono_field_is_deleted_with_flags (field, flags))
3783 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3784 if (bflags & BFLAGS_Public)
3786 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3787 if (bflags & BFLAGS_NonPublic) {
3794 if (flags & FIELD_ATTRIBUTE_STATIC) {
3795 if (bflags & BFLAGS_Static)
3796 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3799 if (bflags & BFLAGS_Instance)
3806 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3809 g_ptr_array_add (ptr_array, field);
3811 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3817 g_ptr_array_free (ptr_array, TRUE);
3822 method_nonpublic (MonoMethod* method, gboolean start_klass)
3824 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3825 case METHOD_ATTRIBUTE_ASSEM:
3826 return (start_klass || mono_defaults.generic_ilist_class);
3827 case METHOD_ATTRIBUTE_PRIVATE:
3829 case METHOD_ATTRIBUTE_PUBLIC:
3837 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3840 MonoClass *startklass;
3844 /*FIXME, use MonoBitSet*/
3845 guint32 method_slots_default [8];
3846 guint32 *method_slots = NULL;
3847 int (*compare_func) (const char *s1, const char *s2) = NULL;
3849 array = g_ptr_array_new ();
3851 mono_error_init (error);
3854 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3856 /* An optimization for calls made from Delegate:CreateDelegate () */
3857 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3858 method = mono_get_delegate_invoke (klass);
3861 g_ptr_array_add (array, method);
3865 mono_class_setup_methods (klass);
3866 mono_class_setup_vtable (klass);
3867 if (mono_class_has_failure (klass))
3870 if (is_generic_parameter (&klass->byval_arg))
3871 nslots = mono_class_get_vtable_size (klass->parent);
3873 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3874 if (nslots >= sizeof (method_slots_default) * 8) {
3875 method_slots = g_new0 (guint32, nslots / 32 + 1);
3877 method_slots = method_slots_default;
3878 memset (method_slots, 0, sizeof (method_slots_default));
3881 mono_class_setup_methods (klass);
3882 mono_class_setup_vtable (klass);
3883 if (mono_class_has_failure (klass))
3887 while ((method = mono_class_get_methods (klass, &iter))) {
3889 if (method->slot != -1) {
3890 g_assert (method->slot < nslots);
3891 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3893 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3894 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3897 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3899 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3900 if (bflags & BFLAGS_Public)
3902 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3908 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3909 if (bflags & BFLAGS_Static)
3910 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3913 if (bflags & BFLAGS_Instance)
3921 if (compare_func (name, method->name))
3926 g_ptr_array_add (array, method);
3928 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3930 if (method_slots != method_slots_default)
3931 g_free (method_slots);
3936 if (method_slots != method_slots_default)
3937 g_free (method_slots);
3938 g_ptr_array_free (array, TRUE);
3940 g_assert (mono_class_has_failure (klass));
3941 mono_error_set_for_class_failure (error, klass);
3945 ICALL_EXPORT GPtrArray*
3946 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionTypeHandle ref_type, const char *mname, guint32 bflags, MonoBoolean ignore_case, MonoError *error)
3948 mono_error_init (error);
3949 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3951 MonoClass *klass = mono_class_from_mono_type (type);
3953 return g_ptr_array_new ();
3956 return mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, error);
3959 ICALL_EXPORT GPtrArray*
3960 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionTypeHandle ref_type, guint32 bflags, MonoError *error)
3962 mono_error_init (error);
3963 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
3965 return g_ptr_array_new ();
3968 MonoClass *startklass, *klass;
3969 klass = startklass = mono_class_from_mono_type (type);
3971 mono_class_setup_methods (klass);
3972 if (mono_class_has_failure (klass)) {
3973 mono_error_set_for_class_failure (error, klass);
3978 GPtrArray *res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3981 gpointer iter = NULL;
3982 while ((method = mono_class_get_methods (klass, &iter))) {
3984 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3986 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3987 if (bflags & BFLAGS_Public)
3990 if (bflags & BFLAGS_NonPublic)
3996 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3997 if (bflags & BFLAGS_Static)
3998 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4001 if (bflags & BFLAGS_Instance)
4007 g_ptr_array_add (res_array, method);
4014 property_hash (gconstpointer data)
4016 MonoProperty *prop = (MonoProperty*)data;
4018 return g_str_hash (prop->name);
4022 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4024 if (method1->slot != -1 && method1->slot == method2->slot)
4027 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4028 if (method1->is_inflated)
4029 method1 = ((MonoMethodInflated*) method1)->declaring;
4030 if (method2->is_inflated)
4031 method2 = ((MonoMethodInflated*) method2)->declaring;
4034 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4038 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4040 // Properties are hide-by-name-and-signature
4041 if (!g_str_equal (prop1->name, prop2->name))
4044 /* If we see a property in a generic method, we want to
4045 compare the generic signatures, not the inflated signatures
4046 because we might conflate two properties that were
4050 public T this[T t] { getter { return t; } } // method 1
4051 public U this[U u] { getter { return u; } } // method 2
4054 If we see int Foo<int,int>::Item[int] we need to know if
4055 the indexer came from method 1 or from method 2, and we
4056 shouldn't conflate them. (Bugzilla 36283)
4058 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4061 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4068 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4073 return method_nonpublic (accessor, start_klass);
4076 ICALL_EXPORT GPtrArray*
4077 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionTypeHandle ref_type, gchar *propname, guint32 bflags, MonoBoolean ignore_case, MonoError *error)
4079 mono_error_init (error);
4080 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4084 return g_ptr_array_new ();
4088 MonoClass *startklass, *klass;
4089 klass = startklass = mono_class_from_mono_type (type);
4091 int (*compare_func) (const char *s1, const char *s2) = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4093 GPtrArray *res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4095 GHashTable *properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4098 mono_class_setup_methods (klass);
4099 mono_class_setup_vtable (klass);
4100 if (mono_class_has_failure (klass)) {
4101 mono_error_set_for_class_failure (error, klass);
4106 gpointer iter = NULL;
4107 while ((prop = mono_class_get_properties (klass, &iter))) {
4109 MonoMethod *method = prop->get;
4114 flags = method->flags;
4115 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4116 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4117 if (bflags & BFLAGS_Public)
4119 } else if (bflags & BFLAGS_NonPublic) {
4120 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4121 property_accessor_nonpublic(prop->set, startklass == klass)) {
4128 if (flags & METHOD_ATTRIBUTE_STATIC) {
4129 if (bflags & BFLAGS_Static)
4130 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4133 if (bflags & BFLAGS_Instance)
4141 if (propname != NULL && compare_func (propname, prop->name))
4144 if (g_hash_table_lookup (properties, prop))
4147 g_ptr_array_add (res_array, prop);
4149 g_hash_table_insert (properties, prop, prop);
4151 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4154 g_hash_table_destroy (properties);
4161 g_hash_table_destroy (properties);
4162 g_ptr_array_free (res_array, TRUE);
4168 event_hash (gconstpointer data)
4170 MonoEvent *event = (MonoEvent*)data;
4172 return g_str_hash (event->name);
4176 event_equal (MonoEvent *event1, MonoEvent *event2)
4178 // Events are hide-by-name
4179 return g_str_equal (event1->name, event2->name);
4182 ICALL_EXPORT GPtrArray*
4183 ves_icall_RuntimeType_GetEvents_native (MonoReflectionTypeHandle ref_type, char *utf8_name, guint32 bflags, MonoError *error)
4185 mono_error_init (error);
4186 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4189 return g_ptr_array_new ();
4192 int (*compare_func) (const char *s1, const char *s2) = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4194 GPtrArray *res_array = g_ptr_array_sized_new (4);
4196 MonoClass *startklass, *klass;
4197 klass = startklass = mono_class_from_mono_type (type);
4199 GHashTable *events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4201 mono_class_setup_methods (klass);
4202 mono_class_setup_vtable (klass);
4203 if (mono_class_has_failure (klass)) {
4204 mono_error_set_for_class_failure (error, klass);
4209 gpointer iter = NULL;
4210 while ((event = mono_class_get_events (klass, &iter))) {
4212 MonoMethod *method = event->add;
4214 method = event->remove;
4216 method = event->raise;
4218 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4219 if (bflags & BFLAGS_Public)
4221 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4222 if (bflags & BFLAGS_NonPublic)
4227 if (bflags & BFLAGS_NonPublic)
4233 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4234 if (bflags & BFLAGS_Static)
4235 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4238 if (bflags & BFLAGS_Instance)
4243 if (bflags & BFLAGS_Instance)
4248 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4251 if (g_hash_table_lookup (events, event))
4254 g_ptr_array_add (res_array, event);
4256 g_hash_table_insert (events, event, event);
4258 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4261 g_hash_table_destroy (events);
4267 g_hash_table_destroy (events);
4269 g_ptr_array_free (res_array, TRUE);
4274 ICALL_EXPORT GPtrArray *
4275 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionTypeHandle ref_type, char *str, guint32 bflags, MonoError *error)
4277 mono_error_init (error);
4278 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
4281 return g_ptr_array_new ();
4284 MonoClass *klass = mono_class_from_mono_type (type);
4287 * If a nested type is generic, return its generic type definition.
4288 * Note that this means that the return value is essentially the set
4289 * of nested types of the generic type definition of @klass.
4291 * A note in MSDN claims that a generic type definition can have
4292 * nested types that aren't generic. In any case, the container of that
4293 * nested type would be the generic type definition.
4295 if (mono_class_is_ginst (klass))
4296 klass = mono_class_get_generic_class (klass)->container_class;
4298 GPtrArray *res_array = g_ptr_array_new ();
4301 gpointer iter = NULL;
4302 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4304 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4305 if (bflags & BFLAGS_Public)
4308 if (bflags & BFLAGS_NonPublic)
4314 if (str != NULL && strcmp (nested->name, str))
4317 g_ptr_array_add (res_array, &nested->byval_arg);
4324 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4326 HANDLE_FUNCTION_ENTER ();
4327 mono_error_init (error);
4328 MonoType *type = NULL;
4329 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4330 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4331 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4332 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4333 HANDLE_FUNCTION_RETURN_VAL (type);
4337 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4339 HANDLE_FUNCTION_ENTER ();
4340 mono_error_init (error);
4341 MonoType *type = NULL;
4342 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4343 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4344 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4345 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4346 HANDLE_FUNCTION_RETURN_VAL (type);
4349 ICALL_EXPORT MonoReflectionTypeHandle
4350 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4352 mono_error_init (error);
4354 MonoTypeNameParse info;
4355 gboolean type_resolve;
4357 /* On MS.NET, this does not fire a TypeResolve event */
4358 type_resolve = TRUE;
4359 char *str = mono_string_handle_to_utf8 (name, error);
4363 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4364 if (!mono_reflection_parse_type (str, &info)) {
4366 mono_reflection_free_type_info (&info);
4368 mono_error_set_argument (error, "name", "failed to parse the type");
4371 /*g_print ("failed parse\n");*/
4372 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4375 if (info.assembly.name) {
4377 mono_reflection_free_type_info (&info);
4379 /* 1.0 and 2.0 throw different exceptions */
4380 if (mono_defaults.generic_ilist_class)
4381 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4383 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4386 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4389 MonoType *type = NULL;
4390 if (!MONO_HANDLE_IS_NULL (module)) {
4391 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4393 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4394 if (!is_ok (error)) {
4396 mono_reflection_free_type_info (&info);
4402 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4403 if (assembly_is_dynamic (assembly)) {
4404 /* Enumerate all modules */
4405 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4406 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4409 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4410 MONO_HANDLE_GET (modules, abuilder, modules);
4411 if (!MONO_HANDLE_IS_NULL (modules)) {
4412 int n = mono_array_handle_length (modules);
4413 for (i = 0; i < n; ++i) {
4414 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4415 if (!is_ok (error)) {
4417 mono_reflection_free_type_info (&info);
4425 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4426 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4427 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4428 int n = mono_array_handle_length (loaded_modules);
4429 for (i = 0; i < n; ++i) {
4430 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4432 if (!is_ok (error)) {
4434 mono_reflection_free_type_info (&info);
4443 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4444 if (!is_ok (error)) {
4446 mono_reflection_free_type_info (&info);
4452 mono_reflection_free_type_info (&info);
4456 MonoError inner_error;
4457 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4458 mono_error_assert_ok (&inner_error);
4459 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4460 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4461 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4465 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4468 if (type->type == MONO_TYPE_CLASS) {
4469 MonoClass *klass = mono_type_get_class (type);
4471 /* need to report exceptions ? */
4472 if (throwOnError && mono_class_has_failure (klass)) {
4473 /* report SecurityException (or others) that occured when loading the assembly */
4474 mono_error_set_for_class_failure (error, klass);
4479 /* g_print ("got it\n"); */
4480 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4482 g_assert (!is_ok (error));
4483 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4487 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4490 gchar *shadow_ini_file;
4493 /* Check for shadow-copied assembly */
4494 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4495 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4497 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4498 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4504 g_free (shadow_ini_file);
4505 if (content != NULL) {
4508 *filename = content;
4515 ICALL_EXPORT MonoStringHandle
4516 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4518 mono_error_init (error);
4519 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4520 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4524 if (g_path_is_absolute (mass->image->name)) {
4525 absolute = g_strdup (mass->image->name);
4526 dirname = g_path_get_dirname (absolute);
4528 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4529 dirname = g_strdup (mass->basedir);
4532 replace_shadow_path (domain, dirname, &absolute);
4535 mono_icall_make_platform_path (absolute);
4539 uri = g_filename_to_uri (absolute, NULL, NULL);
4541 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4542 uri = g_strconcat (prepend, absolute, NULL);
4547 MonoStringHandle res;
4549 res = mono_string_new_handle (domain, uri, error);
4552 res = MONO_HANDLE_NEW (MonoString, NULL);
4557 ICALL_EXPORT MonoBoolean
4558 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4560 mono_error_init (error);
4561 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4563 return mass->in_gac;
4566 ICALL_EXPORT MonoReflectionAssemblyHandle
4567 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4570 MonoImageOpenStatus status;
4571 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4573 name = mono_string_handle_to_utf8 (mname, error);
4576 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4582 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4587 ICALL_EXPORT MonoStringHandle
4588 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4590 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4591 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4592 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4595 ICALL_EXPORT MonoBoolean
4596 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4598 mono_error_init (error);
4599 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4600 return assembly->ref_only;
4603 ICALL_EXPORT MonoStringHandle
4604 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4606 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4607 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4609 return mono_string_new_handle (domain, assembly->image->version, error);
4612 ICALL_EXPORT MonoReflectionMethodHandle
4613 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4615 mono_error_init (error);
4616 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4617 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4620 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4621 guint32 token = mono_image_get_entry_point (assembly->image);
4625 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4629 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4634 ICALL_EXPORT MonoReflectionModuleHandle
4635 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4637 mono_error_init (error);
4638 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4639 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4640 return mono_module_get_object_handle (domain, a->image, error);
4644 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4646 HANDLE_FUNCTION_ENTER ();
4647 mono_error_init (error);
4648 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4649 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4652 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4654 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4657 ICALL_EXPORT MonoArrayHandle
4658 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4660 mono_error_init (error);
4661 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4662 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4663 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4664 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4669 for (i = 0; i < table->rows; ++i) {
4670 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4675 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4678 ICALL_EXPORT MonoStringHandle
4679 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4681 char *guid = mono_runtime_get_aotid ();
4684 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4689 static MonoAssemblyName*
4690 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4692 mono_error_init (error);
4693 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4695 mono_assembly_get_assemblyref (image, i, aname);
4696 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4697 /* name and culture are pointers into the image tables, but we need
4698 * real malloc'd strings (so that we can g_free() them later from
4699 * Mono.RuntimeMarshal.FreeAssemblyName) */
4700 aname->name = g_strdup (aname->name);
4701 aname->culture = g_strdup (aname->culture);
4702 /* Don't need the hash value in managed */
4703 aname->hash_value = NULL;
4704 aname->hash_len = 0;
4705 g_assert (aname->public_key == NULL);
4707 /* note: this function doesn't return the codebase on purpose (i.e. it can
4708 be used under partial trust as path information isn't present). */
4712 ICALL_EXPORT GPtrArray*
4713 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4715 mono_error_init (error);
4716 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4717 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4718 MonoImage *image = ass->image;
4720 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4721 int count = t->rows;
4723 GPtrArray *result = g_ptr_array_sized_new (count);
4725 for (int i = 0; i < count; i++) {
4726 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4729 g_ptr_array_add (result, aname);
4734 /* move this in some file in mono/util/ */
4736 g_concat_dir_and_file (const char *dir, const char *file)
4738 g_return_val_if_fail (dir != NULL, NULL);
4739 g_return_val_if_fail (file != NULL, NULL);
4742 * If the directory name doesn't have a / on the end, we need
4743 * to add one so we get a proper path to the file
4745 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4746 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4748 return g_strconcat (dir, file, NULL);
4752 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4754 mono_error_init (error);
4755 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4756 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4757 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4759 guint32 cols [MONO_MANIFEST_SIZE];
4760 guint32 impl, file_idx;
4764 char *n = mono_string_handle_to_utf8 (name, error);
4765 return_val_if_nok (error, NULL);
4767 for (i = 0; i < table->rows; ++i) {
4768 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4769 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4770 if (strcmp (val, n) == 0)
4774 if (i == table->rows)
4777 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4780 * this code should only be called after obtaining the
4781 * ResourceInfo and handling the other cases.
4783 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4784 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4786 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4787 if (!is_ok (error) || !module)
4791 module = assembly->image;
4794 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4797 MONO_HANDLE_ASSIGN (ref_module, rm);
4799 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4803 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4805 HANDLE_FUNCTION_ENTER ();
4806 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4807 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4808 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4810 guint32 cols [MONO_MANIFEST_SIZE];
4811 guint32 file_cols [MONO_FILE_SIZE];
4815 gboolean result = FALSE;
4817 n = mono_string_handle_to_utf8 (name, error);
4821 for (i = 0; i < table->rows; ++i) {
4822 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4823 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4824 if (strcmp (val, n) == 0)
4828 if (i == table->rows)
4831 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4832 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4835 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4836 case MONO_IMPLEMENTATION_FILE:
4837 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4838 table = &assembly->image->tables [MONO_TABLE_FILE];
4839 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4840 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4841 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4842 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4843 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4845 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4848 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4849 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4850 mono_assembly_load_reference (assembly->image, i - 1);
4851 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4852 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4855 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4858 MONO_HANDLE_SET (info, assembly, assm_obj);
4860 /* Obtain info recursively */
4861 get_manifest_resource_info_internal (assm_obj, name, info, error);
4864 guint32 location = MONO_HANDLE_GETVAL (info, location);
4865 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4866 MONO_HANDLE_SETVAL (info, location, guint32, location);
4869 case MONO_IMPLEMENTATION_EXP_TYPE:
4870 g_assert_not_reached ();
4877 HANDLE_FUNCTION_RETURN_VAL (result);
4880 ICALL_EXPORT gboolean
4881 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4883 mono_error_init (error);
4884 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4888 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4890 HANDLE_FUNCTION_ENTER();
4891 mono_error_init (error);
4892 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4893 char *n = g_concat_dir_and_file (assembly->basedir, val);
4894 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4898 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4900 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4903 ICALL_EXPORT MonoObjectHandle
4904 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4906 mono_error_init (error);
4907 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4908 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4909 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4912 /* check hash if needed */
4913 if (!MONO_HANDLE_IS_NULL(name)) {
4914 char *n = mono_string_handle_to_utf8 (name, error);
4918 for (i = 0; i < table->rows; ++i) {
4919 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4920 if (strcmp (val, n) == 0) {
4922 n = g_concat_dir_and_file (assembly->basedir, val);
4923 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4927 return MONO_HANDLE_CAST (MonoObject, fn);
4935 for (i = 0; i < table->rows; ++i) {
4936 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4940 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4945 for (i = 0; i < table->rows; ++i) {
4946 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4947 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4952 return MONO_HANDLE_CAST (MonoObject, result);
4958 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4960 HANDLE_FUNCTION_ENTER ();
4961 mono_error_init (error);
4963 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4967 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4972 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4976 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4978 HANDLE_FUNCTION_ENTER ();
4979 mono_error_init (error);
4981 guint32 cols [MONO_FILE_SIZE];
4982 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4983 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4984 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4987 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4989 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4993 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4994 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4997 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
5000 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5004 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5007 ICALL_EXPORT MonoArrayHandle
5008 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5010 mono_error_init (error);
5011 MonoDomain *domain = mono_domain_get();
5012 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5014 int i, j, file_count = 0;
5015 MonoImage **modules;
5016 guint32 module_count, real_module_count;
5017 MonoTableInfo *table;
5018 MonoImage *image = assembly->image;
5020 g_assert (image != NULL);
5021 g_assert (!assembly_is_dynamic (assembly));
5023 table = &image->tables [MONO_TABLE_FILE];
5024 file_count = table->rows;
5026 modules = image->modules;
5027 module_count = image->module_count;
5029 real_module_count = 0;
5030 for (i = 0; i < module_count; ++i)
5032 real_module_count ++;
5034 klass = mono_class_get_module_class ();
5035 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5039 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5043 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5046 for (i = 0; i < module_count; ++i)
5047 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5050 for (i = 0; i < file_count; ++i, ++j) {
5051 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5057 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5060 ICALL_EXPORT MonoReflectionMethodHandle
5061 ves_icall_GetCurrentMethod (MonoError *error)
5063 mono_error_init (error);
5065 MonoMethod *m = mono_method_get_last_managed ();
5068 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5069 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5072 while (m->is_inflated)
5073 m = ((MonoMethodInflated*)m)->declaring;
5075 return mono_method_get_object_handle (mono_domain_get (), m, NULL, error);
5080 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5083 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5086 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5087 //method is inflated, we should inflate it on the other class
5088 MonoGenericContext ctx;
5089 ctx.method_inst = inflated->context.method_inst;
5090 ctx.class_inst = inflated->context.class_inst;
5091 if (mono_class_is_ginst (klass))
5092 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5093 else if (mono_class_is_gtd (klass))
5094 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5095 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5096 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5100 mono_class_setup_methods (method->klass);
5101 if (mono_class_has_failure (method->klass))
5103 int mcount = mono_class_get_method_count (method->klass);
5104 for (i = 0; i < mcount; ++i) {
5105 if (method->klass->methods [i] == method) {
5110 mono_class_setup_methods (klass);
5111 if (mono_class_has_failure (klass))
5113 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5114 return klass->methods [offset];
5117 ICALL_EXPORT MonoReflectionMethodHandle
5118 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check, MonoError *error)
5120 mono_error_init (error);
5122 if (type && generic_check) {
5123 klass = mono_class_from_mono_type (type);
5124 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5125 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5127 if (method->klass != klass) {
5128 method = mono_method_get_equivalent_method (method, klass);
5130 return MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE);
5133 klass = mono_class_from_mono_type (type);
5135 klass = method->klass;
5136 return mono_method_get_object_handle (mono_domain_get (), method, klass, error);
5139 ICALL_EXPORT MonoReflectionMethodBodyHandle
5140 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method, MonoError *error)
5142 mono_error_init (error);
5143 return mono_method_body_get_object_handle (mono_domain_get (), method, error);
5146 ICALL_EXPORT MonoReflectionAssemblyHandle
5147 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5149 mono_error_init (error);
5151 MonoMethod *dest = NULL;
5152 mono_stack_walk_no_il (get_executing, &dest);
5154 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5158 ICALL_EXPORT MonoReflectionAssemblyHandle
5159 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5161 mono_error_init (error);
5163 MonoDomain* domain = mono_domain_get ();
5165 if (!domain->entry_assembly)
5166 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5168 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5171 ICALL_EXPORT MonoReflectionAssemblyHandle
5172 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5174 mono_error_init (error);
5179 mono_stack_walk_no_il (get_executing, &dest);
5181 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5185 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5186 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5188 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5191 ICALL_EXPORT MonoStringHandle
5192 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5193 gboolean assembly_qualified, MonoError *error)
5195 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5196 MonoType *type = MONO_HANDLE_RAW (object)->type;
5197 MonoTypeNameFormat format;
5198 MonoStringHandle res;
5202 format = assembly_qualified ?
5203 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5204 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5206 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5208 name = mono_type_get_name_full (type, format);
5210 return NULL_HANDLE_STRING;
5212 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5214 return NULL_HANDLE_STRING;
5217 res = mono_string_new_handle (domain, name, error);
5224 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionTypeHandle rfield, MonoError *error)
5226 mono_error_init (error);
5227 MonoType *type = MONO_HANDLE_GETVAL (rfield, type);
5228 MonoClass *klass = mono_class_from_mono_type (type);
5230 mono_class_init_checked (klass, error);
5233 return mono_security_core_clr_class_level (klass);
5237 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5239 MonoClassField *field = rfield->field;
5240 return mono_security_core_clr_field_level (field, TRUE);
5244 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5246 MonoMethod *method = rfield->method;
5247 return mono_security_core_clr_method_level (method, TRUE);
5250 ICALL_EXPORT MonoStringHandle
5251 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5253 mono_error_init (error);
5254 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5255 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5258 name = mono_stringify_assembly_name (&mass->aname);
5259 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5264 ICALL_EXPORT MonoAssemblyName *
5265 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5267 return &mass->aname;
5271 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5274 MonoImageOpenStatus status = MONO_IMAGE_OK;
5275 char *codebase = NULL;
5280 mono_error_init (error);
5282 filename = mono_string_handle_to_utf8 (fname, error);
5283 return_if_nok (error);
5285 dirname = g_path_get_dirname (filename);
5286 replace_shadow_path (mono_domain_get (), dirname, &filename);
5289 image = mono_image_open (filename, &status);
5292 if (status == MONO_IMAGE_IMAGE_INVALID)
5293 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5295 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5300 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5302 mono_image_close (image);
5304 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5308 if (filename != NULL && *filename != '\0') {
5311 codebase = g_strdup (filename);
5313 mono_icall_make_platform_path (codebase);
5315 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5317 result = g_strconcat (prepend, codebase, NULL);
5321 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5324 mono_image_close (image);
5328 ICALL_EXPORT MonoBoolean
5329 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5330 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5332 mono_error_init (error);
5333 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5334 MonoBoolean result = FALSE;
5335 MonoDeclSecurityEntry entry;
5337 /* SecurityAction.RequestMinimum */
5338 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5339 *minimum = entry.blob;
5340 *minLength = entry.size;
5343 /* SecurityAction.RequestOptional */
5344 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5345 *optional = entry.blob;
5346 *optLength = entry.size;
5349 /* SecurityAction.RequestRefuse */
5350 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5351 *refused = entry.blob;
5352 *refLength = entry.size;
5360 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5362 guint32 attrs, visibility;
5364 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5365 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5366 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5369 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5375 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5377 mono_error_init (error);
5378 HANDLE_FUNCTION_ENTER ();
5379 MonoError klass_error;
5380 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5383 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5384 return_if_nok (error);
5386 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5388 MonoException *ex = mono_error_convert_to_exception (error);
5389 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5391 HANDLE_FUNCTION_RETURN ();
5394 static MonoArrayHandle
5395 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5397 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5400 mono_error_init (error);
5402 /* we start the count from 1 because we skip the special type <Module> */
5405 for (i = 1; i < tdef->rows; ++i) {
5406 if (mono_module_type_is_visible (tdef, image, i + 1))
5410 count = tdef->rows - 1;
5412 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5413 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5414 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5415 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5417 for (i = 1; i < tdef->rows; ++i) {
5418 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5419 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5420 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5429 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5431 HANDLE_FUNCTION_ENTER ();
5432 mono_error_init (error);
5433 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5434 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5438 /* Append the new types to the end of the array */
5439 if (mono_array_handle_length (res2) > 0) {
5442 len1 = mono_array_handle_length (res);
5443 len2 = mono_array_handle_length (res2);
5445 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5449 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5450 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5451 MONO_HANDLE_ASSIGN (res, res3);
5453 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5457 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5458 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5459 MONO_HANDLE_ASSIGN (exceptions, ex3);
5462 HANDLE_FUNCTION_RETURN ();
5466 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5468 HANDLE_FUNCTION_ENTER ();
5469 MonoError unboxed_error;
5470 mono_error_init (&unboxed_error);
5471 mono_error_set_for_class_failure (&unboxed_error, klass);
5473 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5474 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5475 HANDLE_FUNCTION_RETURN ();
5478 ICALL_EXPORT MonoArrayHandle
5479 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5481 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5484 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5485 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5487 g_assert (!assembly_is_dynamic (assembly));
5488 MonoImage *image = assembly->image;
5489 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5490 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5491 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5493 /* Append data from all modules in the assembly */
5494 for (i = 0; i < table->rows; ++i) {
5495 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5496 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5497 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5500 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5501 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5506 /* the ReflectionTypeLoadException must have all the types (Types property),
5507 * NULL replacing types which throws an exception. The LoaderException must
5508 * contain all exceptions for NULL items.
5511 int len = mono_array_handle_length (res);
5515 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5516 for (i = 0; i < len; i++) {
5517 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5519 if (!MONO_HANDLE_IS_NULL (t)) {
5520 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5521 if ((klass != NULL) && mono_class_has_failure (klass)) {
5522 /* keep the class in the list */
5523 list = g_list_append (list, klass);
5524 /* and replace Type with NULL */
5525 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5532 if (list || ex_count) {
5534 int j, length = g_list_length (list) + ex_count;
5536 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5537 if (!is_ok (error)) {
5539 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5541 /* Types for which mono_class_get_checked () succeeded */
5542 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5543 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5544 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5546 /* Types for which it don't */
5547 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5548 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5549 if (!MONO_HANDLE_IS_NULL (exc)) {
5550 g_assert (i < length);
5551 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5558 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5559 if (!is_ok (error)) {
5560 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5562 mono_error_set_exception_handle (error, exc);
5563 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5570 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5572 mono_assembly_name_free (aname);
5577 ICALL_EXPORT gboolean
5578 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5580 *is_version_definited = *is_token_defined = FALSE;
5582 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5585 ICALL_EXPORT MonoReflectionTypeHandle
5586 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5588 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5589 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5594 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5596 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5597 /* These images do not have a global type */
5600 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5604 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5610 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5612 /*if (module->image)
5613 mono_image_close (module->image);*/
5616 ICALL_EXPORT MonoStringHandle
5617 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5619 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5620 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5623 return mono_string_new_handle (domain, image->guid, error);
5627 static inline gpointer
5628 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5630 return (gpointer) (-1);
5632 #endif /* HOST_WIN32 */
5634 ICALL_EXPORT gpointer
5635 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5637 return mono_icall_module_get_hinstance (module);
5641 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5643 if (image_is_dynamic (image)) {
5644 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5645 *pe_kind = dyn->pe_kind;
5646 *machine = dyn->machine;
5649 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5650 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5655 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5657 return (image->md_version_major << 16) | (image->md_version_minor);
5660 ICALL_EXPORT MonoArrayHandle
5661 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5663 mono_error_init (error);
5665 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5666 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5669 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5672 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5673 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5674 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5676 int n = mono_array_handle_length (exceptions);
5677 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5678 for (int i = 0; i < n; ++i) {
5679 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5680 if (!MONO_HANDLE_IS_NULL (ex)) {
5681 mono_error_set_exception_handle (error, ex);
5682 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5690 mono_memberref_is_method (MonoImage *image, guint32 token)
5692 if (!image_is_dynamic (image)) {
5693 guint32 cols [MONO_MEMBERREF_SIZE];
5695 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5696 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5697 mono_metadata_decode_blob_size (sig, &sig);
5698 return (*sig != 0x6);
5701 MonoClass *handle_class;
5703 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5704 mono_error_cleanup (&error); /* just probing, ignore error */
5708 return mono_defaults.methodhandle_class == handle_class;
5712 static MonoGenericInst *
5713 get_generic_inst_from_array_handle (MonoArrayHandle type_args)
5715 int type_argc = mono_array_handle_length (type_args);
5716 int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
5718 MonoGenericInst *ginst = (MonoGenericInst *)g_alloca (size);
5719 memset (ginst, 0, sizeof (MonoGenericInst));
5720 ginst->type_argc = type_argc;
5721 for (int i = 0; i < type_argc; i++) {
5722 MONO_HANDLE_ARRAY_GETVAL (ginst->type_argv[i], type_args, MonoType*, i);
5724 ginst->is_open = FALSE;
5725 for (int i = 0; i < type_argc; i++) {
5726 if (mono_class_is_open_constructed_type (ginst->type_argv[i])) {
5727 ginst->is_open = TRUE;
5732 return mono_metadata_get_canonical_generic_inst (ginst);
5736 init_generic_context_from_args_handles (MonoGenericContext *context, MonoArrayHandle type_args, MonoArrayHandle method_args)
5738 if (!MONO_HANDLE_IS_NULL (type_args)) {
5739 context->class_inst = get_generic_inst_from_array_handle (type_args);
5741 context->class_inst = NULL;
5743 if (!MONO_HANDLE_IS_NULL (method_args)) {
5744 context->method_inst = get_generic_inst_from_array_handle (method_args);
5746 context->method_inst = NULL;
5752 module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5754 HANDLE_FUNCTION_ENTER ();
5755 mono_error_init (error);
5756 MonoType *result = NULL;
5758 int table = mono_metadata_token_table (token);
5759 int index = mono_metadata_token_index (token);
5760 MonoGenericContext context;
5762 *resolve_error = ResolveTokenError_Other;
5764 /* Validate token */
5765 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5766 (table != MONO_TABLE_TYPESPEC)) {
5767 *resolve_error = ResolveTokenError_BadTable;
5771 if (image_is_dynamic (image)) {
5772 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5773 MonoError inner_error;
5774 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5775 mono_error_cleanup (&inner_error);
5776 result = klass ? &klass->byval_arg : NULL;
5780 init_generic_context_from_args_handles (&context, type_args, method_args);
5781 MonoError inner_error;
5782 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5783 mono_error_cleanup (&inner_error);
5784 result = klass ? &klass->byval_arg : NULL;
5788 if ((index <= 0) || (index > image->tables [table].rows)) {
5789 *resolve_error = ResolveTokenError_OutOfRange;
5793 init_generic_context_from_args_handles (&context, type_args, method_args);
5794 klass = mono_class_get_checked (image, token, error);
5796 klass = mono_class_inflate_generic_class_checked (klass, &context, error);
5801 result = &klass->byval_arg;
5803 HANDLE_FUNCTION_RETURN_VAL (result);
5806 ICALL_EXPORT MonoType*
5807 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5809 return module_resolve_type_token (image, token, type_args, method_args, resolve_error, error);
5813 module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5815 HANDLE_FUNCTION_ENTER ();
5816 mono_error_init (error);
5817 MonoMethod *method = NULL;
5818 int table = mono_metadata_token_table (token);
5819 int index = mono_metadata_token_index (token);
5820 MonoGenericContext context;
5822 *resolve_error = ResolveTokenError_Other;
5824 /* Validate token */
5825 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5826 (table != MONO_TABLE_MEMBERREF)) {
5827 *resolve_error = ResolveTokenError_BadTable;
5831 if (image_is_dynamic (image)) {
5832 if (table == MONO_TABLE_METHOD) {
5833 MonoError inner_error;
5834 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5835 mono_error_cleanup (&inner_error);
5839 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5840 *resolve_error = ResolveTokenError_BadTable;
5844 init_generic_context_from_args_handles (&context, type_args, method_args);
5845 MonoError inner_error;
5846 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5847 mono_error_cleanup (&inner_error);
5851 if ((index <= 0) || (index > image->tables [table].rows)) {
5852 *resolve_error = ResolveTokenError_OutOfRange;
5855 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5856 *resolve_error = ResolveTokenError_BadTable;
5860 init_generic_context_from_args_handles (&context, type_args, method_args);
5861 method = mono_get_method_checked (image, token, NULL, &context, error);
5864 HANDLE_FUNCTION_RETURN_VAL (method);
5867 ICALL_EXPORT MonoMethod*
5868 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5870 return module_resolve_method_token (image, token, type_args, method_args, resolve_error, error);
5873 ICALL_EXPORT MonoString*
5874 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5877 int index = mono_metadata_token_index (token);
5879 *resolve_error = ResolveTokenError_Other;
5881 /* Validate token */
5882 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5883 *resolve_error = ResolveTokenError_BadTable;
5887 if (image_is_dynamic (image)) {
5888 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5889 mono_error_cleanup (&error);
5893 if ((index <= 0) || (index >= image->heap_us.size)) {
5894 *resolve_error = ResolveTokenError_OutOfRange;
5898 /* FIXME: What to do if the index points into the middle of a string ? */
5900 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5901 mono_error_set_pending_exception (&error);
5905 static MonoClassField*
5906 module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5908 HANDLE_FUNCTION_ENTER ();
5910 int table = mono_metadata_token_table (token);
5911 int index = mono_metadata_token_index (token);
5912 MonoGenericContext context;
5913 MonoClassField *field = NULL;
5915 mono_error_init (error);
5916 *resolve_error = ResolveTokenError_Other;
5918 /* Validate token */
5919 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5920 *resolve_error = ResolveTokenError_BadTable;
5924 if (image_is_dynamic (image)) {
5925 if (table == MONO_TABLE_FIELD) {
5926 MonoError inner_error;
5927 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5928 mono_error_cleanup (&inner_error);
5932 if (mono_memberref_is_method (image, token)) {
5933 *resolve_error = ResolveTokenError_BadTable;
5937 init_generic_context_from_args_handles (&context, type_args, method_args);
5938 MonoError inner_error;
5939 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5940 mono_error_cleanup (&inner_error);
5944 if ((index <= 0) || (index > image->tables [table].rows)) {
5945 *resolve_error = ResolveTokenError_OutOfRange;
5948 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5949 *resolve_error = ResolveTokenError_BadTable;
5953 init_generic_context_from_args_handles (&context, type_args, method_args);
5954 field = mono_field_from_token_checked (image, token, &klass, &context, error);
5957 HANDLE_FUNCTION_RETURN_VAL (field);
5960 ICALL_EXPORT MonoClassField*
5961 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5963 return module_resolve_field_token (image, token, type_args, method_args, resolve_error, error);
5966 ICALL_EXPORT MonoObjectHandle
5967 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *error, MonoError *merror)
5969 int table = mono_metadata_token_table (token);
5971 mono_error_init (merror);
5972 *error = ResolveTokenError_Other;
5975 case MONO_TABLE_TYPEDEF:
5976 case MONO_TABLE_TYPEREF:
5977 case MONO_TABLE_TYPESPEC: {
5978 MonoType *t = module_resolve_type_token (image, token, type_args, method_args, error, merror);
5980 return MONO_HANDLE_CAST (MonoObject, mono_type_get_object_handle (mono_domain_get (), t, merror));
5985 case MONO_TABLE_METHOD:
5986 case MONO_TABLE_METHODSPEC: {
5987 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
5989 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
5993 case MONO_TABLE_FIELD: {
5994 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
5996 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6001 case MONO_TABLE_MEMBERREF:
6002 if (mono_memberref_is_method (image, token)) {
6003 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
6005 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
6010 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
6012 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6020 *error = ResolveTokenError_BadTable;
6026 ICALL_EXPORT MonoArrayHandle
6027 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error, MonoError *error)
6029 mono_error_init (error);
6030 int table = mono_metadata_token_table (token);
6031 int idx = mono_metadata_token_index (token);
6032 MonoTableInfo *tables = image->tables;
6036 *resolve_error = ResolveTokenError_OutOfRange;
6038 /* FIXME: Support other tables ? */
6039 if (table != MONO_TABLE_STANDALONESIG)
6040 return MONO_HANDLE_CAST (MonoArray, NULL);
6042 if (image_is_dynamic (image))
6043 return MONO_HANDLE_CAST (MonoArray, NULL);
6045 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6046 return MONO_HANDLE_CAST (MonoArray, NULL);
6048 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6050 ptr = mono_metadata_blob_heap (image, sig);
6051 len = mono_metadata_decode_blob_size (ptr, &ptr);
6053 MonoArrayHandle res = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, len, error);
6055 return MONO_HANDLE_CAST (MonoArray, NULL);
6057 gpointer array_base = MONO_ARRAY_HANDLE_PIN (res, guint8, 0, &h);
6058 memcpy (array_base, ptr, len);
6059 mono_gchandle_free (h);
6063 ICALL_EXPORT MonoBoolean
6064 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionTypeHandle ref_type, MonoError *error)
6066 mono_error_init (error);
6067 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6069 MonoBoolean res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6075 check_for_invalid_type (MonoClass *klass, MonoError *error)
6079 mono_error_init (error);
6081 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6084 name = mono_type_get_full_name (klass);
6085 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6087 ICALL_EXPORT MonoReflectionTypeHandle
6088 ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int rank, MonoError *error)
6090 mono_error_init (error);
6091 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6093 MonoClass *klass = mono_class_from_mono_type (type);
6094 check_for_invalid_type (klass, error);
6096 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6099 if (rank == 0) //single dimentional array
6100 aklass = mono_array_class_get (klass, 1);
6102 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6104 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6105 return mono_type_get_object_handle (domain, &aklass->byval_arg, error);
6108 ICALL_EXPORT MonoReflectionTypeHandle
6109 ves_icall_RuntimeType_make_byref_type (MonoReflectionTypeHandle ref_type, MonoError *error)
6111 mono_error_init (error);
6112 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6114 MonoClass *klass = mono_class_from_mono_type (type);
6115 mono_class_init_checked (klass, error);
6117 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6119 check_for_invalid_type (klass, error);
6121 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6123 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6124 return mono_type_get_object_handle (domain, &klass->this_arg, error);
6127 ICALL_EXPORT MonoReflectionTypeHandle
6128 ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type, MonoError *error)
6130 mono_error_init (error);
6131 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
6132 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
6133 MonoClass *klass = mono_class_from_mono_type (type);
6134 mono_class_init_checked (klass, error);
6136 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6138 check_for_invalid_type (klass, error);
6140 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
6142 MonoClass *pklass = mono_ptr_class_get (type);
6144 return mono_type_get_object_handle (domain, &pklass->byval_arg, error);
6147 ICALL_EXPORT MonoObject *
6148 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6149 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6152 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6153 MonoObject *delegate;
6155 MonoMethod *method = info->method;
6156 MonoMethodSignature *sig = mono_method_signature(method);
6158 mono_class_init_checked (delegate_class, &error);
6159 if (mono_error_set_pending_exception (&error))
6162 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6163 /* FIXME improve this exception message */
6164 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6166 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6167 mono_error_set_pending_exception (&error);
6171 if (mono_security_core_clr_enabled ()) {
6172 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6173 if (throwOnBindFailure)
6174 mono_error_set_pending_exception (&error);
6176 mono_error_cleanup (&error);
6181 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6182 if (!method->is_inflated) {
6183 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"));
6188 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6189 if (mono_error_set_pending_exception (&error))
6192 if (method_is_dynamic (method)) {
6193 /* Creating a trampoline would leak memory */
6194 func = mono_compile_method_checked (method, &error);
6195 if (mono_error_set_pending_exception (&error))
6198 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6199 method = mono_object_get_virtual_method (target, method);
6200 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6201 if (mono_error_set_pending_exception (&error))
6203 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6206 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6207 if (mono_error_set_pending_exception (&error))
6212 ICALL_EXPORT MonoMulticastDelegate *
6213 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6216 MonoMulticastDelegate *ret;
6218 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6220 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6221 if (mono_error_set_pending_exception (&error))
6224 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6229 ICALL_EXPORT MonoReflectionMethod*
6230 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6232 MonoReflectionMethod *ret = NULL;
6234 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6235 mono_error_set_pending_exception (&error);
6241 static inline gint32
6242 mono_array_get_byte_length (MonoArray *array)
6248 klass = array->obj.vtable->klass;
6250 if (array->bounds == NULL)
6251 length = array->max_length;
6254 for (i = 0; i < klass->rank; ++ i)
6255 length *= array->bounds [i].length;
6258 switch (klass->element_class->byval_arg.type) {
6261 case MONO_TYPE_BOOLEAN:
6265 case MONO_TYPE_CHAR:
6273 return length * sizeof (gpointer);
6284 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6286 return mono_array_get_byte_length (array);
6290 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6292 return mono_array_get (array, gint8, idx);
6296 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6298 mono_array_set (array, gint8, idx, value);
6301 ICALL_EXPORT MonoBoolean
6302 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6304 guint8 *src_buf, *dest_buf;
6307 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6311 g_assert (count >= 0);
6313 /* This is called directly from the class libraries without going through the managed wrapper */
6314 MONO_CHECK_ARG_NULL (src, FALSE);
6315 MONO_CHECK_ARG_NULL (dest, FALSE);
6317 /* watch out for integer overflow */
6318 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6321 src_buf = (guint8 *)src->vector + src_offset;
6322 dest_buf = (guint8 *)dest->vector + dest_offset;
6325 memcpy (dest_buf, src_buf, count);
6327 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6332 #ifndef DISABLE_REMOTING
6333 ICALL_EXPORT MonoObjectHandle
6334 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObjectHandle this_obj, MonoStringHandle class_name, MonoError *error)
6336 mono_error_init (error);
6337 MonoDomain *domain = MONO_HANDLE_DOMAIN (this_obj);
6338 MonoRealProxyHandle rp = MONO_HANDLE_CAST (MonoRealProxy, this_obj);
6340 MonoObjectHandle res = MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, error));
6344 MonoTransparentProxyHandle tp = MONO_HANDLE_CAST (MonoTransparentProxy, res);
6346 MONO_HANDLE_SET (tp, rp, rp);
6348 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
6349 MONO_HANDLE_GET (reftype, rp, class_to_proxy);
6350 MonoType *type = MONO_HANDLE_GETVAL (reftype, type);
6351 MonoClass *klass = mono_class_from_mono_type (type);
6353 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6354 mono_class_setup_vtable (klass);
6355 if (mono_class_has_failure (klass)) {
6356 mono_error_set_for_class_failure (error, klass);
6360 MonoObjectHandle remoting_obj = mono_object_handle_isinst (this_obj, mono_defaults.iremotingtypeinfo_class, error);
6363 MONO_HANDLE_SETVAL (tp, custom_type_info, MonoBoolean, !MONO_HANDLE_IS_NULL (remoting_obj));
6365 MonoRemoteClass *remote_class = mono_remote_class (domain, class_name, klass, error);
6368 MONO_HANDLE_SETVAL (tp, remote_class, MonoRemoteClass*, remote_class);
6370 MONO_HANDLE_SETVAL (res, vtable, MonoVTable*, mono_remote_class_vtable (domain, remote_class, rp, error));
6376 ICALL_EXPORT MonoReflectionType *
6377 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6380 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6381 mono_error_set_pending_exception (&error);
6387 /* System.Environment */
6390 ves_icall_System_Environment_get_UserName (void)
6392 /* using glib is more portable */
6393 return mono_string_new (mono_domain_get (), g_get_user_name ());
6398 mono_icall_get_machine_name (void)
6400 #if !defined(DISABLE_SOCKETS)
6404 #if defined _SC_HOST_NAME_MAX
6405 n = sysconf (_SC_HOST_NAME_MAX);
6409 buf = g_malloc (n+1);
6411 if (gethostname (buf, n) == 0){
6413 result = mono_string_new (mono_domain_get (), buf);
6420 return mono_string_new (mono_domain_get (), "mono");
6423 #endif /* !HOST_WIN32 */
6425 ICALL_EXPORT MonoString *
6426 ves_icall_System_Environment_get_MachineName (void)
6428 return mono_icall_get_machine_name ();
6433 mono_icall_get_platform (void)
6435 #if defined(__MACH__)
6438 // Notice that the value is hidden from user code, and only exposed
6439 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6440 // define and making assumptions based on Unix/128/4 values before there
6441 // was a MacOS define. Lots of code would assume that not-Unix meant
6442 // Windows, but in this case, it would be OSX.
6450 #endif /* !HOST_WIN32 */
6453 ves_icall_System_Environment_get_Platform (void)
6455 return mono_icall_get_platform ();
6459 static inline MonoString *
6460 mono_icall_get_new_line (void)
6462 return mono_string_new (mono_domain_get (), "\n");
6464 #endif /* !HOST_WIN32 */
6466 ICALL_EXPORT MonoString *
6467 ves_icall_System_Environment_get_NewLine (void)
6469 return mono_icall_get_new_line ();
6473 static inline MonoBoolean
6474 mono_icall_is_64bit_os (void)
6476 #if SIZEOF_VOID_P == 8
6479 #if defined(HAVE_SYS_UTSNAME_H)
6480 struct utsname name;
6482 if (uname (&name) >= 0) {
6483 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6489 #endif /* !HOST_WIN32 */
6491 ICALL_EXPORT MonoBoolean
6492 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6494 return mono_icall_is_64bit_os ();
6497 ICALL_EXPORT MonoStringHandle
6498 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6502 if (utf8_name == NULL)
6503 return NULL_HANDLE_STRING;
6505 value = g_getenv (utf8_name);
6508 return NULL_HANDLE_STRING;
6510 return mono_string_new_handle (mono_domain_get (), value, error);
6514 * There is no standard way to get at environ.
6517 #ifndef __MINGW32_VERSION
6518 #if defined(__APPLE__)
6519 #if defined (TARGET_OSX)
6520 /* Apple defines this in crt_externs.h but doesn't provide that header for
6521 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6522 * in fact exist on all implementations (so far)
6524 gchar ***_NSGetEnviron(void);
6525 #define environ (*_NSGetEnviron())
6527 static char *mono_environ[1] = { NULL };
6528 #define environ mono_environ
6529 #endif /* defined (TARGET_OSX) */
6537 ICALL_EXPORT MonoArray *
6538 ves_icall_System_Environment_GetCoomandLineArgs (void)
6541 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6542 mono_error_set_pending_exception (&error);
6548 mono_icall_get_environment_variable_names (void)
6558 for (e = environ; *e != 0; ++ e)
6561 domain = mono_domain_get ();
6562 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6563 if (mono_error_set_pending_exception (&error))
6567 for (e = environ; *e != 0; ++ e) {
6568 parts = g_strsplit (*e, "=", 2);
6570 str = mono_string_new (domain, *parts);
6571 mono_array_setref (names, n, str);
6581 #endif /* !HOST_WIN32 */
6583 ICALL_EXPORT MonoArray *
6584 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6586 return mono_icall_get_environment_variable_names ();
6591 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6593 gchar *utf8_name, *utf8_value;
6596 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6597 if (mono_error_set_pending_exception (&error))
6600 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6601 g_unsetenv (utf8_name);
6606 utf8_value = mono_string_to_utf8_checked (value, &error);
6607 if (!mono_error_ok (&error)) {
6609 mono_error_set_pending_exception (&error);
6612 g_setenv (utf8_name, utf8_value, TRUE);
6615 g_free (utf8_value);
6617 #endif /* !HOST_WIN32 */
6620 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6622 mono_icall_set_environment_variable (name, value);
6626 ves_icall_System_Environment_Exit (int result)
6628 mono_environment_exitcode_set (result);
6630 /* FIXME: There are some cleanup hangs that should be worked out, but
6631 * if the program is going to exit, everything will be cleaned up when
6632 * NaCl exits anyway.
6634 #ifndef __native_client__
6635 if (!mono_runtime_try_shutdown ())
6636 mono_thread_exit ();
6638 /* Suspend all managed threads since the runtime is going away */
6639 mono_thread_suspend_all_other_threads ();
6641 mono_runtime_quit ();
6644 /* we may need to do some cleanup here... */
6648 ICALL_EXPORT MonoStringHandle
6649 ves_icall_System_Environment_GetGacPath (MonoError *error)
6651 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6655 static inline MonoString *
6656 mono_icall_get_windows_folder_path (int folder)
6658 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6659 return mono_string_new (mono_domain_get (), "");
6661 #endif /* !HOST_WIN32 */
6663 ICALL_EXPORT MonoString*
6664 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6666 return mono_icall_get_windows_folder_path (folder);
6669 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6671 mono_icall_get_logical_drives (void)
6674 gunichar2 buf [256], *ptr, *dname;
6676 guint initial_size = 127, size = 128;
6679 MonoString *drivestr;
6680 MonoDomain *domain = mono_domain_get ();
6686 while (size > initial_size) {
6687 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6688 if (size > initial_size) {
6691 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6692 initial_size = size;
6706 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6707 if (mono_error_set_pending_exception (&error))
6714 while (*u16) { u16++; len ++; }
6715 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6716 if (mono_error_set_pending_exception (&error))
6719 mono_array_setref (result, ndrives++, drivestr);
6729 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6731 ICALL_EXPORT MonoArray *
6732 ves_icall_System_Environment_GetLogicalDrives (void)
6734 return mono_icall_get_logical_drives ();
6737 ICALL_EXPORT MonoString *
6738 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6741 gunichar2 volume_name [MAX_PATH + 1];
6743 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6745 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6746 mono_error_set_pending_exception (&error);
6750 ICALL_EXPORT MonoStringHandle
6751 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6753 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6756 static const char *encodings [] = {
6758 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6759 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6760 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6762 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6763 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6764 "x_unicode_2_0_utf_7",
6766 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6767 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6769 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6772 "unicodefffe", "utf_16be",
6779 * Returns the internal codepage, if the value of "int_code_page" is
6780 * 1 at entry, and we can not compute a suitable code page number,
6781 * returns the code page as a string
6783 ICALL_EXPORT MonoString*
6784 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6789 char *codepage = NULL;
6791 int want_name = *int_code_page;
6794 *int_code_page = -1;
6796 g_get_charset (&cset);
6797 c = codepage = g_strdup (cset);
6798 for (c = codepage; *c; c++){
6799 if (isascii (*c) && isalpha (*c))
6804 /* g_print ("charset: %s\n", cset); */
6806 /* handle some common aliases */
6809 for (i = 0; p != 0; ){
6812 p = encodings [++i];
6815 if (strcmp (p, codepage) == 0){
6816 *int_code_page = code;
6819 p = encodings [++i];
6822 if (strstr (codepage, "utf_8") != NULL)
6823 *int_code_page |= 0x10000000;
6826 if (want_name && *int_code_page == -1)
6827 return mono_string_new (mono_domain_get (), cset);
6832 ICALL_EXPORT MonoBoolean
6833 ves_icall_System_Environment_get_HasShutdownStarted (void)
6835 if (mono_runtime_is_shutting_down ())
6838 if (mono_domain_is_unloading (mono_domain_get ()))
6846 mono_icall_broadcast_setting_change (void)
6850 #endif /* !HOST_WIN32 */
6853 ves_icall_System_Environment_BroadcastSettingChange (void)
6855 mono_icall_broadcast_setting_change ();
6860 ves_icall_System_Environment_get_TickCount (void)
6862 /* this will overflow after ~24 days */
6863 return (gint32) (mono_msec_boottime () & 0xffffffff);
6867 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6872 #ifndef DISABLE_REMOTING
6873 ICALL_EXPORT MonoBoolean
6874 ves_icall_IsTransparentProxy (MonoObject *proxy)
6879 if (mono_object_is_transparent_proxy (proxy))
6885 ICALL_EXPORT MonoReflectionMethod *
6886 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6887 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6889 MonoReflectionMethod *ret = NULL;
6894 MonoMethod **vtable;
6895 MonoMethod *res = NULL;
6897 MONO_CHECK_ARG_NULL (rtype, NULL);
6898 MONO_CHECK_ARG_NULL (rmethod, NULL);
6900 method = rmethod->method;
6901 klass = mono_class_from_mono_type (rtype->type);
6902 mono_class_init_checked (klass, &error);
6903 if (mono_error_set_pending_exception (&error))
6906 if (MONO_CLASS_IS_INTERFACE (klass))
6909 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6912 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6913 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6919 mono_class_setup_vtable (klass);
6920 vtable = klass->vtable;
6922 if (mono_class_is_interface (method->klass)) {
6923 gboolean variance_used = FALSE;
6924 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6925 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6927 res = vtable [offs + method->slot];
6929 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6932 if (method->slot != -1)
6933 res = vtable [method->slot];
6939 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6940 mono_error_set_pending_exception (&error);
6945 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6951 klass = mono_class_from_mono_type (type->type);
6952 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6953 if (!is_ok (&error)) {
6954 mono_error_set_pending_exception (&error);
6958 mono_vtable_set_is_remote (vtable, enable);
6961 #else /* DISABLE_REMOTING */
6964 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6966 g_assert_not_reached ();
6971 ICALL_EXPORT MonoObject *
6972 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6979 domain = mono_object_domain (type);
6980 klass = mono_class_from_mono_type (type->type);
6981 mono_class_init_checked (klass, &error);
6982 if (mono_error_set_pending_exception (&error))
6985 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6986 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6990 if (klass->rank >= 1) {
6991 g_assert (klass->rank == 1);
6992 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6993 mono_error_set_pending_exception (&error);
6996 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6997 if (!is_ok (&error)) {
6998 mono_error_set_pending_exception (&error);
7001 /* Bypass remoting object creation check */
7002 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7003 mono_error_set_pending_exception (&error);
7009 ICALL_EXPORT MonoStringHandle
7010 ves_icall_System_IO_get_temp_path (MonoError *error)
7012 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7015 #ifndef PLATFORM_NO_DRIVEINFO
7016 ICALL_EXPORT MonoBoolean
7017 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7018 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7022 ULARGE_INTEGER wapi_free_bytes_avail;
7023 ULARGE_INTEGER wapi_total_number_of_bytes;
7024 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7026 *error = ERROR_SUCCESS;
7027 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7028 &wapi_total_number_of_free_bytes);
7031 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7032 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7033 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7035 *free_bytes_avail = 0;
7036 *total_number_of_bytes = 0;
7037 *total_number_of_free_bytes = 0;
7038 *error = GetLastError ();
7044 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7045 static inline guint32
7046 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7048 return GetDriveType (mono_string_chars (root_path_name));
7050 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7052 ICALL_EXPORT guint32
7053 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7055 return mono_icall_drive_info_get_drive_type (root_path_name);
7058 #endif /* PLATFORM_NO_DRIVEINFO */
7060 ICALL_EXPORT gpointer
7061 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7064 gpointer result = mono_compile_method_checked (method, &error);
7065 mono_error_set_pending_exception (&error);
7069 ICALL_EXPORT MonoString *
7070 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7075 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7077 mono_icall_make_platform_path (path);
7079 mcpath = mono_string_new (mono_domain_get (), path);
7085 /* this is an icall */
7087 get_bundled_app_config (void)
7090 const gchar *app_config;
7093 gchar *config_file_name, *config_file_path;
7094 gsize len, config_file_path_length, config_ext_length;
7097 domain = mono_domain_get ();
7098 file = domain->setup->configuration_file;
7099 if (!file || file->length == 0)
7102 // Retrieve config file and remove the extension
7103 config_file_name = mono_string_to_utf8_checked (file, &error);
7104 if (mono_error_set_pending_exception (&error))
7106 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7107 if (!config_file_path)
7108 config_file_path = config_file_name;
7110 config_file_path_length = strlen (config_file_path);
7111 config_ext_length = strlen (".config");
7112 if (config_file_path_length <= config_ext_length)
7115 len = config_file_path_length - config_ext_length;
7116 module = (gchar *)g_malloc0 (len + 1);
7117 memcpy (module, config_file_path, len);
7118 // Get the config file from the module name
7119 app_config = mono_config_string_for_assembly_file (module);
7122 if (config_file_name != config_file_path)
7123 g_free (config_file_name);
7124 g_free (config_file_path);
7129 return mono_string_new (mono_domain_get (), app_config);
7132 static MonoStringHandle
7133 get_bundled_machine_config (MonoError *error)
7135 const gchar *machine_config;
7137 machine_config = mono_get_machine_config ();
7139 if (!machine_config)
7140 return NULL_HANDLE_STRING;
7142 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7145 ICALL_EXPORT MonoStringHandle
7146 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7148 return get_bundled_machine_config (error);
7152 ICALL_EXPORT MonoStringHandle
7153 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7155 return get_bundled_machine_config (error);
7158 ICALL_EXPORT MonoStringHandle
7159 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7161 return get_bundled_machine_config (error);
7165 ICALL_EXPORT MonoString *
7166 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7171 path = g_path_get_dirname (mono_get_config_dir ());
7173 mono_icall_make_platform_path (path);
7175 ipath = mono_string_new (mono_domain_get (), path);
7181 ICALL_EXPORT gboolean
7182 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7184 mono_error_init (error);
7185 MonoPEResourceDataEntry *entry;
7188 if (!assembly || !result || !size)
7193 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7194 image = assm->image;
7195 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7199 *result = mono_image_rva_map (image, entry->rde_data_offset);
7204 *size = entry->rde_size;
7209 ICALL_EXPORT MonoBoolean
7210 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7212 return mono_is_debugger_attached ();
7215 ICALL_EXPORT MonoBoolean
7216 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7218 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7219 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7225 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7227 if (mono_get_runtime_callbacks ()->debug_log)
7228 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7233 mono_icall_write_windows_debug_string (MonoString *message)
7235 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7237 #endif /* !HOST_WIN32 */
7240 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7242 mono_icall_write_windows_debug_string (message);
7245 /* Only used for value types */
7246 ICALL_EXPORT MonoObjectHandle
7247 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionTypeHandle ref_type, MonoError *error)
7249 mono_error_init (error);
7250 MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
7251 MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
7252 MonoClass *klass = mono_class_from_mono_type (type);
7254 mono_class_init_checked (klass, error);
7258 if (mono_class_is_nullable (klass))
7259 /* No arguments -> null */
7262 return MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (domain, klass, error));
7265 ICALL_EXPORT MonoReflectionMethod *
7266 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7268 MonoReflectionMethod *ret = NULL;
7271 MonoClass *klass, *parent;
7272 MonoGenericContext *generic_inst = NULL;
7273 MonoMethod *method = m->method;
7274 MonoMethod *result = NULL;
7277 if (method->klass == NULL)
7280 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7281 MONO_CLASS_IS_INTERFACE (method->klass) ||
7282 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7285 slot = mono_method_get_vtable_slot (method);
7289 klass = method->klass;
7290 if (mono_class_is_ginst (klass)) {
7291 generic_inst = mono_class_get_context (klass);
7292 klass = mono_class_get_generic_class (klass)->container_class;
7297 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7298 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7299 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7300 or klass is the generic container class and generic_inst is the instantiation.
7302 when we go to the parent, if the parent is an open constructed type, we need to
7303 replace the type parameters by the definitions from the generic_inst, and then take it
7304 apart again into the klass and the generic_inst.
7306 For cases like this:
7307 class C<T> : B<T, int> {
7308 public override void Foo () { ... }
7310 class B<U,V> : A<HashMap<U,V>> {
7311 public override void Foo () { ... }
7314 public virtual void Foo () { ... }
7317 if at each iteration the parent isn't open, we can skip inflating it. if at some
7318 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7321 MonoGenericContext *parent_inst = NULL;
7322 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7323 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7324 if (!mono_error_ok (&error)) {
7325 mono_error_set_pending_exception (&error);
7329 if (mono_class_is_ginst (parent)) {
7330 parent_inst = mono_class_get_context (parent);
7331 parent = mono_class_get_generic_class (parent)->container_class;
7334 mono_class_setup_vtable (parent);
7335 if (parent->vtable_size <= slot)
7338 generic_inst = parent_inst;
7341 klass = klass->parent;
7344 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7345 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7346 if (!mono_error_ok (&error)) {
7347 mono_error_set_pending_exception (&error);
7351 generic_inst = NULL;
7353 if (mono_class_is_ginst (klass)) {
7354 generic_inst = mono_class_get_context (klass);
7355 klass = mono_class_get_generic_class (klass)->container_class;
7361 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7362 if (!mono_error_ok (&error)) {
7363 mono_error_set_pending_exception (&error);
7368 if (klass == method->klass)
7371 /*This is possible if definition == FALSE.
7372 * Do it here to be really sure we don't read invalid memory.
7374 if (slot >= klass->vtable_size)
7377 mono_class_setup_vtable (klass);
7379 result = klass->vtable [slot];
7380 if (result == NULL) {
7381 /* It is an abstract method */
7382 gboolean found = FALSE;
7383 gpointer iter = NULL;
7384 while ((result = mono_class_get_methods (klass, &iter))) {
7385 if (result->slot == slot) {
7390 /* found might be FALSE if we looked in an abstract class
7391 * that doesn't override an abstract method of its
7393 * abstract class Base {
7394 * public abstract void Foo ();
7396 * abstract class Derived : Base { }
7397 * class Child : Derived {
7398 * public override void Foo () { }
7401 * if m was Child.Foo and we ask for the base method,
7402 * then we get here with klass == Derived and found == FALSE
7404 /* but it shouldn't be the case that if we're looking
7405 * for the definition and didn't find a result; the
7406 * loop above should've taken us as far as we could
7408 g_assert (!(definition && !found));
7413 g_assert (result != NULL);
7415 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7416 mono_error_set_pending_exception (&error);
7420 ICALL_EXPORT MonoString*
7421 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7423 MonoMethod *method = m->method;
7425 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7430 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7432 iter->sig = *(MonoMethodSignature**)argsp;
7434 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7435 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7438 /* FIXME: it's not documented what start is exactly... */
7442 iter->args = argsp + sizeof (gpointer);
7444 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7446 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7449 ICALL_EXPORT MonoTypedRef
7450 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7452 guint32 i, arg_size;
7456 i = iter->sig->sentinelpos + iter->next_arg;
7458 g_assert (i < iter->sig->param_count);
7460 res.type = iter->sig->params [i];
7461 res.klass = mono_class_from_mono_type (res.type);
7462 arg_size = mono_type_stack_size (res.type, &align);
7463 #if defined(__arm__) || defined(__mips__)
7464 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7466 res.value = iter->args;
7467 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7468 /* Values are stored as 8 byte register sized objects, but 'value'
7469 * is dereferenced as a pointer in other routines.
7471 res.value = (char*)res.value + 4;
7473 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7474 if (arg_size <= sizeof (gpointer)) {
7476 int padding = arg_size - mono_type_size (res.type, &dummy);
7477 res.value = (guint8*)res.value + padding;
7480 iter->args = (char*)iter->args + arg_size;
7483 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7488 ICALL_EXPORT MonoTypedRef
7489 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7491 guint32 i, arg_size;
7495 i = iter->sig->sentinelpos + iter->next_arg;
7497 g_assert (i < iter->sig->param_count);
7499 while (i < iter->sig->param_count) {
7500 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7502 res.type = iter->sig->params [i];
7503 res.klass = mono_class_from_mono_type (res.type);
7504 /* FIXME: endianess issue... */
7505 arg_size = mono_type_stack_size (res.type, &align);
7506 #if defined(__arm__) || defined(__mips__)
7507 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7509 res.value = iter->args;
7510 iter->args = (char*)iter->args + arg_size;
7512 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7515 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7523 ICALL_EXPORT MonoType*
7524 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7528 i = iter->sig->sentinelpos + iter->next_arg;
7530 g_assert (i < iter->sig->param_count);
7532 return iter->sig->params [i];
7535 ICALL_EXPORT MonoObject*
7536 mono_TypedReference_ToObject (MonoTypedRef* tref)
7539 MonoObject *result = NULL;
7540 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7541 MonoObject** objp = (MonoObject **)tref->value;
7545 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7546 mono_error_set_pending_exception (&error);
7550 ICALL_EXPORT MonoTypedRef
7551 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7554 MonoReflectionField *f;
7556 MonoType *ftype = NULL;
7560 memset (&res, 0, sizeof (res));
7563 g_assert (mono_array_length (fields) > 0);
7565 klass = target->vtable->klass;
7567 for (i = 0; i < mono_array_length (fields); ++i) {
7568 f = mono_array_get (fields, MonoReflectionField*, i);
7570 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7573 if (f->field->parent != klass) {
7574 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7578 p = (guint8*)target + f->field->offset;
7580 p += f->field->offset - sizeof (MonoObject);
7581 klass = mono_class_from_mono_type (f->field->type);
7582 ftype = f->field->type;
7586 res.klass = mono_class_from_mono_type (ftype);
7593 prelink_method (MonoMethod *method, MonoError *error)
7595 const char *exc_class, *exc_arg;
7597 mono_error_init (error);
7598 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7600 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7602 mono_error_set_exception_instance (error,
7603 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7606 /* create the wrapper, too? */
7610 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7614 prelink_method (method->method, &error);
7615 mono_error_set_pending_exception (&error);
7619 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7622 MonoClass *klass = mono_class_from_mono_type (type->type);
7624 gpointer iter = NULL;
7626 mono_class_init_checked (klass, &error);
7627 if (mono_error_set_pending_exception (&error))
7630 while ((m = mono_class_get_methods (klass, &iter))) {
7631 prelink_method (m, &error);
7632 if (mono_error_set_pending_exception (&error))
7637 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7639 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7640 gint32 const **exponents,
7641 gunichar2 const **digitLowerTable,
7642 gunichar2 const **digitUpperTable,
7643 gint64 const **tenPowersList,
7644 gint32 const **decHexDigits)
7646 *mantissas = Formatter_MantissaBitsTable;
7647 *exponents = Formatter_TensExponentTable;
7648 *digitLowerTable = Formatter_DigitLowerTable;
7649 *digitUpperTable = Formatter_DigitUpperTable;
7650 *tenPowersList = Formatter_TenPowersList;
7651 *decHexDigits = Formatter_DecHexDigits;
7655 add_modifier_to_array (MonoDomain *domain, MonoImage *image, MonoCustomMod *modifier, MonoArrayHandle dest, int dest_idx, MonoError *error)
7657 HANDLE_FUNCTION_ENTER ();
7658 mono_error_init (error);
7659 MonoClass *klass = mono_class_get_checked (image, modifier->token, error);
7663 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
7667 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rt);
7669 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
7673 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7674 * and avoid useless allocations.
7676 static MonoArrayHandle
7677 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7680 MonoDomain *domain = mono_domain_get ();
7682 mono_error_init (error);
7683 for (i = 0; i < type->num_mods; ++i) {
7684 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7688 return MONO_HANDLE_NEW (MonoArray, NULL);
7690 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
7694 for (i = 0; i < type->num_mods; ++i) {
7695 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7696 if (!add_modifier_to_array (domain, image, &type->modifiers[i], res, count , error))
7703 return MONO_HANDLE_NEW (MonoArray, NULL);
7706 ICALL_EXPORT MonoArrayHandle
7707 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameterHandle param, MonoBoolean optional, MonoError *error)
7709 mono_error_init (error);
7710 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
7711 MONO_HANDLE_GET (rt, param, ClassImpl);
7712 MonoType *type = MONO_HANDLE_GETVAL (rt, type);
7713 MonoObjectHandle member = MONO_HANDLE_NEW (MonoObject, NULL);
7714 MONO_HANDLE_GET (member, param, MemberImpl);
7715 MonoClass *member_class = mono_handle_class (member);
7716 MonoMethod *method = NULL;
7719 MonoMethodSignature *sig;
7721 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7722 method = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod, member), method);
7723 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7724 MonoProperty *prop = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionProperty, member), property);
7725 if (!(method = prop->get))
7729 char *type_name = mono_type_get_full_name (member_class);
7730 mono_error_set_not_supported (error, "Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7732 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7735 image = method->klass->image;
7736 pos = MONO_HANDLE_GETVAL (param, PositionImpl);
7737 sig = mono_method_signature (method);
7741 type = sig->params [pos];
7743 return type_array_from_modifiers (image, type, optional, error);
7747 get_property_type (MonoProperty *prop)
7749 MonoMethodSignature *sig;
7751 sig = mono_method_signature (prop->get);
7753 } else if (prop->set) {
7754 sig = mono_method_signature (prop->set);
7755 return sig->params [sig->param_count - 1];
7760 ICALL_EXPORT MonoArrayHandle
7761 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, MonoError *error)
7763 mono_error_init (error);
7764 MonoProperty *prop = MONO_HANDLE_GETVAL (property, property);
7765 MonoClass *klass = MONO_HANDLE_GETVAL (property, klass);
7766 MonoType *type = get_property_type (prop);
7767 MonoImage *image = klass->image;
7770 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7771 return type_array_from_modifiers (image, type, optional, error);
7775 *Construct a MonoType suited to be used to decode a constant blob object.
7777 * @type is the target type which will be constructed
7778 * @blob_type is the blob type, for example, that comes from the constant table
7779 * @real_type is the expected constructed type.
7782 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7784 type->type = blob_type;
7785 type->data.klass = NULL;
7786 if (blob_type == MONO_TYPE_CLASS)
7787 type->data.klass = mono_defaults.object_class;
7788 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7789 /* For enums, we need to use the base type */
7790 type->type = MONO_TYPE_VALUETYPE;
7791 type->data.klass = mono_class_from_mono_type (real_type);
7793 type->data.klass = mono_class_from_mono_type (real_type);
7796 ICALL_EXPORT MonoObject*
7797 property_info_get_default_value (MonoReflectionProperty *property)
7801 MonoProperty *prop = property->property;
7802 MonoType *type = get_property_type (prop);
7803 MonoDomain *domain = mono_object_domain (property);
7804 MonoTypeEnum def_type;
7805 const char *def_value;
7808 mono_class_init (prop->parent);
7810 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7811 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7815 def_value = mono_class_get_property_default_value (prop, &def_type);
7817 mono_type_from_blob_type (&blob_type, def_type, type);
7818 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7820 mono_error_set_pending_exception (&error);
7824 ICALL_EXPORT MonoBoolean
7825 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7828 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7829 MonoCustomAttrInfo *cinfo;
7832 mono_class_init_checked (attr_class, &error);
7833 if (mono_error_set_pending_exception (&error))
7836 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7837 if (!is_ok (&error)) {
7838 mono_error_set_pending_exception (&error);
7843 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7845 mono_custom_attrs_free (cinfo);
7849 ICALL_EXPORT MonoArray*
7850 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7852 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7857 mono_class_init_checked (attr_class, &error);
7858 if (mono_error_set_pending_exception (&error))
7862 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7863 if (!mono_error_ok (&error)) {
7864 mono_error_set_pending_exception (&error);
7871 ICALL_EXPORT MonoArray*
7872 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7876 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7877 mono_error_set_pending_exception (&error);
7882 ICALL_EXPORT MonoStringHandle
7883 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7886 MonoStringHandle display_name;
7888 mono_error_init (error);
7889 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7890 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7892 return display_name;
7896 static inline gint32
7897 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7899 return WAIT_TIMEOUT;
7901 #endif /* !HOST_WIN32 */
7904 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7906 return mono_icall_wait_for_input_idle (handle, milliseconds);
7910 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7912 return mono_process_current_pid ();
7915 ICALL_EXPORT MonoBoolean
7916 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7928 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7930 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7934 ICALL_EXPORT MonoObject*
7935 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7937 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7942 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7944 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7948 ICALL_EXPORT MonoObject*
7949 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7951 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7955 ICALL_EXPORT MonoBoolean
7956 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7958 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7963 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7965 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7969 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7971 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7976 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7978 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7982 ICALL_EXPORT mono_unichar2*
7983 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7985 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7992 #ifndef DISABLE_ICALL_TABLES
7994 #define ICALL_TYPE(id,name,first)
7995 #define ICALL(id,name,func) Icall_ ## id,
7996 #define HANDLES(inner) inner
7999 #include "metadata/icall-def.h"
8005 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8006 #define ICALL(id,name,func)
8008 #define HANDLES(inner) inner
8010 #include "metadata/icall-def.h"
8016 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8017 #define ICALL(id,name,func)
8019 #define HANDLES(inner) inner
8021 guint16 first_icall;
8024 static const IcallTypeDesc
8025 icall_type_descs [] = {
8026 #include "metadata/icall-def.h"
8030 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8033 #define HANDLES(inner) inner
8035 #define ICALL_TYPE(id,name,first)
8038 #ifdef HAVE_ARRAY_ELEM_INIT
8039 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8040 #define MSGSTRFIELD1(line) str##line
8042 static const struct msgstrtn_t {
8043 #define ICALL(id,name,func)
8045 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8046 #include "metadata/icall-def.h"
8048 } icall_type_names_str = {
8049 #define ICALL_TYPE(id,name,first) (name),
8050 #include "metadata/icall-def.h"
8053 static const guint16 icall_type_names_idx [] = {
8054 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8055 #include "metadata/icall-def.h"
8058 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8060 static const struct msgstr_t {
8062 #define ICALL_TYPE(id,name,first)
8063 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8064 #include "metadata/icall-def.h"
8066 } icall_names_str = {
8067 #define ICALL(id,name,func) (name),
8068 #include "metadata/icall-def.h"
8071 static const guint16 icall_names_idx [] = {
8072 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8073 #include "metadata/icall-def.h"
8076 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8082 #define ICALL_TYPE(id,name,first) name,
8083 #define ICALL(id,name,func)
8084 static const char* const
8085 icall_type_names [] = {
8086 #include "metadata/icall-def.h"
8090 #define icall_type_name_get(id) (icall_type_names [(id)])
8094 #define ICALL_TYPE(id,name,first)
8095 #define ICALL(id,name,func) name,
8096 static const char* const
8098 #include "metadata/icall-def.h"
8101 #define icall_name_get(id) icall_names [(id)]
8103 #endif /* !HAVE_ARRAY_ELEM_INIT */
8106 #define HANDLES(inner) inner
8109 #define ICALL_TYPE(id,name,first)
8110 #define ICALL(id,name,func) func,
8111 static const gconstpointer
8112 icall_functions [] = {
8113 #include "metadata/icall-def.h"
8117 #ifdef ENABLE_ICALL_SYMBOL_MAP
8119 #define HANDLES(inner) inner
8122 #define ICALL_TYPE(id,name,first)
8123 #define ICALL(id,name,func) #func,
8124 static const gconstpointer
8125 icall_symbols [] = {
8126 #include "metadata/icall-def.h"
8133 #define ICALL_TYPE(id,name,first)
8134 #define ICALL(id,name,func) 0,
8136 #define HANDLES(inner) 1,
8138 icall_uses_handles [] = {
8139 #include "metadata/icall-def.h"
8144 #endif /* DISABLE_ICALL_TABLES */
8146 static mono_mutex_t icall_mutex;
8147 static GHashTable *icall_hash = NULL;
8148 static GHashTable *jit_icall_hash_name = NULL;
8149 static GHashTable *jit_icall_hash_addr = NULL;
8152 mono_icall_init (void)
8154 #ifndef DISABLE_ICALL_TABLES
8157 /* check that tables are sorted: disable in release */
8160 const char *prev_class = NULL;
8161 const char *prev_method;
8163 for (i = 0; i < Icall_type_num; ++i) {
8164 const IcallTypeDesc *desc;
8167 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8168 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8169 prev_class = icall_type_name_get (i);
8170 desc = &icall_type_descs [i];
8171 num_icalls = icall_desc_num_icalls (desc);
8172 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8173 for (j = 0; j < num_icalls; ++j) {
8174 const char *methodn = icall_name_get (desc->first_icall + j);
8175 if (prev_method && strcmp (prev_method, methodn) >= 0)
8176 g_print ("method %s should come before method %s\n", methodn, prev_method);
8177 prev_method = methodn;
8183 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8184 mono_os_mutex_init (&icall_mutex);
8188 mono_icall_lock (void)
8190 mono_locks_os_acquire (&icall_mutex, IcallLock);
8194 mono_icall_unlock (void)
8196 mono_locks_os_release (&icall_mutex, IcallLock);
8200 mono_icall_cleanup (void)
8202 g_hash_table_destroy (icall_hash);
8203 g_hash_table_destroy (jit_icall_hash_name);
8204 g_hash_table_destroy (jit_icall_hash_addr);
8205 mono_os_mutex_destroy (&icall_mutex);
8209 * mono_add_internal_call:
8210 * @name: method specification to surface to the managed world
8211 * @method: pointer to a C method to invoke when the method is called
8213 * This method surfaces the C function pointed by @method as a method
8214 * that has been surfaced in managed code with the method specified in
8215 * @name as an internal call.
8217 * Internal calls are surfaced to all app domains loaded and they are
8218 * accessibly by a type with the specified name.
8220 * You must provide a fully qualified type name, that is namespaces
8221 * and type name, followed by a colon and the method name, with an
8222 * optional signature to bind.
8224 * For example, the following are all valid declarations:
8226 * "MyApp.Services.ScriptService:Accelerate"
8227 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8229 * You use method parameters in cases where there might be more than
8230 * one surface method to managed code. That way you can register different
8231 * internal calls for different method overloads.
8233 * The internal calls are invoked with no marshalling. This means that .NET
8234 * types like System.String are exposed as `MonoString *` parameters. This is
8235 * different than the way that strings are surfaced in P/Invoke.
8237 * For more information on how the parameters are marshalled, see the
8238 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8241 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8242 * reference for more information on the format of method descriptions.
8245 mono_add_internal_call (const char *name, gconstpointer method)
8249 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8251 mono_icall_unlock ();
8254 #ifndef DISABLE_ICALL_TABLES
8256 #ifdef HAVE_ARRAY_ELEM_INIT
8258 compare_method_imap (const void *key, const void *elem)
8260 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8261 return strcmp (key, method_name);
8265 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8267 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);
8270 return (nameslot - &icall_names_idx [0]);
8274 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8276 gsize slotnum = find_slot_icall (imap, name);
8279 return (gboolean)icall_uses_handles [slotnum];
8283 find_method_icall (const IcallTypeDesc *imap, const char *name)
8285 gsize slotnum = find_slot_icall (imap, name);
8288 return (gpointer)icall_functions [slotnum];
8292 compare_class_imap (const void *key, const void *elem)
8294 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8295 return strcmp (key, class_name);
8298 static const IcallTypeDesc*
8299 find_class_icalls (const char *name)
8301 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);
8304 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8307 #else /* HAVE_ARRAY_ELEM_INIT */
8310 compare_method_imap (const void *key, const void *elem)
8312 const char** method_name = (const char**)elem;
8313 return strcmp (key, *method_name);
8317 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8319 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8322 return nameslot - icall_names;
8326 find_method_icall (const IcallTypeDesc *imap, const char *name)
8328 gsize slotnum = find_slot_icall (imap, name);
8331 return (gpointer)icall_functions [slotnum];
8335 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8337 gsize slotnum = find_slot_icall (imap, name);
8340 return (gboolean)icall_uses_handles [slotnum];
8344 compare_class_imap (const void *key, const void *elem)
8346 const char** class_name = (const char**)elem;
8347 return strcmp (key, *class_name);
8350 static const IcallTypeDesc*
8351 find_class_icalls (const char *name)
8353 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8356 return &icall_type_descs [nameslot - icall_type_names];
8359 #endif /* HAVE_ARRAY_ELEM_INIT */
8361 #endif /* DISABLE_ICALL_TABLES */
8364 * we should probably export this as an helper (handle nested types).
8365 * Returns the number of chars written in buf.
8368 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8370 int nspacelen, cnamelen;
8371 nspacelen = strlen (klass->name_space);
8372 cnamelen = strlen (klass->name);
8373 if (nspacelen + cnamelen + 2 > bufsize)
8376 memcpy (buf, klass->name_space, nspacelen);
8377 buf [nspacelen ++] = '.';
8379 memcpy (buf + nspacelen, klass->name, cnamelen);
8380 buf [nspacelen + cnamelen] = 0;
8381 return nspacelen + cnamelen;
8384 #ifdef DISABLE_ICALL_TABLES
8386 no_icall_table (void)
8388 g_assert_not_reached ();
8393 * mono_lookup_internal_call_full:
8394 * @method: the method to look up
8395 * @uses_handles: out argument if method needs handles around managed objects.
8397 * Returns a pointer to the icall code for the given method. If
8398 * uses_handles is not NULL, it will be set to TRUE if the method
8399 * needs managed objects wrapped using the infrastructure in handle.h
8401 * If the method is not found, warns and returns NULL.
8404 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8409 int typelen = 0, mlen, siglen;
8411 #ifndef DISABLE_ICALL_TABLES
8412 const IcallTypeDesc *imap = NULL;
8415 g_assert (method != NULL);
8417 if (method->is_inflated)
8418 method = ((MonoMethodInflated *) method)->declaring;
8420 if (method->klass->nested_in) {
8421 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8425 mname [pos++] = '/';
8428 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8434 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8439 #ifndef DISABLE_ICALL_TABLES
8440 imap = find_class_icalls (mname);
8443 mname [typelen] = ':';
8444 mname [typelen + 1] = ':';
8446 mlen = strlen (method->name);
8447 memcpy (mname + typelen + 2, method->name, mlen);
8448 sigstart = mname + typelen + 2 + mlen;
8451 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8452 siglen = strlen (tmpsig);
8453 if (typelen + mlen + siglen + 6 > sizeof (mname))
8456 memcpy (sigstart + 1, tmpsig, siglen);
8457 sigstart [siglen + 1] = ')';
8458 sigstart [siglen + 2] = 0;
8463 res = g_hash_table_lookup (icall_hash, mname);
8466 *uses_handles = FALSE;
8467 mono_icall_unlock ();;
8470 /* try without signature */
8472 res = g_hash_table_lookup (icall_hash, mname);
8475 *uses_handles = FALSE;
8476 mono_icall_unlock ();
8480 #ifdef DISABLE_ICALL_TABLES
8481 mono_icall_unlock ();
8482 /* Fail only when the result is actually used */
8483 /* mono_marshal_get_native_wrapper () depends on this */
8484 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8485 return ves_icall_System_String_ctor_RedirectToCreateString;
8487 return no_icall_table;
8489 /* it wasn't found in the static call tables */
8492 *uses_handles = FALSE;
8493 mono_icall_unlock ();
8496 res = find_method_icall (imap, sigstart - mlen);
8499 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8500 mono_icall_unlock ();
8503 /* try _with_ signature */
8505 res = find_method_icall (imap, sigstart - mlen);
8508 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8509 mono_icall_unlock ();
8513 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8514 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8515 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8516 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8517 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");
8518 g_print ("If you see other errors or faults after this message they are probably related\n");
8519 g_print ("and you need to fix your mono install first.\n");
8521 mono_icall_unlock ();
8528 mono_lookup_internal_call (MonoMethod *method)
8530 return mono_lookup_internal_call_full (method, NULL);
8533 #ifdef ENABLE_ICALL_SYMBOL_MAP
8535 func_cmp (gconstpointer key, gconstpointer p)
8537 return (gsize)key - (gsize)*(gsize*)p;
8542 * mono_lookup_icall_symbol:
8544 * Given the icall METHOD, returns its C symbol.
8547 mono_lookup_icall_symbol (MonoMethod *m)
8549 #ifdef DISABLE_ICALL_TABLES
8550 g_assert_not_reached ();
8553 #ifdef ENABLE_ICALL_SYMBOL_MAP
8557 static gconstpointer *functions_sorted;
8558 static const char**symbols_sorted;
8559 static gboolean inited;
8564 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8565 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8566 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8567 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8568 /* Bubble sort the two arrays */
8572 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8573 if (functions_sorted [i] > functions_sorted [i + 1]) {
8576 tmp = functions_sorted [i];
8577 functions_sorted [i] = functions_sorted [i + 1];
8578 functions_sorted [i + 1] = tmp;
8579 tmp = symbols_sorted [i];
8580 symbols_sorted [i] = symbols_sorted [i + 1];
8581 symbols_sorted [i + 1] = tmp;
8588 func = mono_lookup_internal_call (m);
8591 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8595 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8597 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8598 g_assert_not_reached ();
8605 type_from_typename (char *type_name)
8607 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8609 if (!strcmp (type_name, "int"))
8610 klass = mono_defaults.int_class;
8611 else if (!strcmp (type_name, "ptr"))
8612 klass = mono_defaults.int_class;
8613 else if (!strcmp (type_name, "void"))
8614 klass = mono_defaults.void_class;
8615 else if (!strcmp (type_name, "int32"))
8616 klass = mono_defaults.int32_class;
8617 else if (!strcmp (type_name, "uint32"))
8618 klass = mono_defaults.uint32_class;
8619 else if (!strcmp (type_name, "int8"))
8620 klass = mono_defaults.sbyte_class;
8621 else if (!strcmp (type_name, "uint8"))
8622 klass = mono_defaults.byte_class;
8623 else if (!strcmp (type_name, "int16"))
8624 klass = mono_defaults.int16_class;
8625 else if (!strcmp (type_name, "uint16"))
8626 klass = mono_defaults.uint16_class;
8627 else if (!strcmp (type_name, "long"))
8628 klass = mono_defaults.int64_class;
8629 else if (!strcmp (type_name, "ulong"))
8630 klass = mono_defaults.uint64_class;
8631 else if (!strcmp (type_name, "float"))
8632 klass = mono_defaults.single_class;
8633 else if (!strcmp (type_name, "double"))
8634 klass = mono_defaults.double_class;
8635 else if (!strcmp (type_name, "object"))
8636 klass = mono_defaults.object_class;
8637 else if (!strcmp (type_name, "obj"))
8638 klass = mono_defaults.object_class;
8639 else if (!strcmp (type_name, "string"))
8640 klass = mono_defaults.string_class;
8641 else if (!strcmp (type_name, "bool"))
8642 klass = mono_defaults.boolean_class;
8643 else if (!strcmp (type_name, "boolean"))
8644 klass = mono_defaults.boolean_class;
8646 g_error ("%s", type_name);
8647 g_assert_not_reached ();
8649 return &klass->byval_arg;
8653 * LOCKING: Take the corlib image lock.
8655 MonoMethodSignature*
8656 mono_create_icall_signature (const char *sigstr)
8661 MonoMethodSignature *res, *res2;
8662 MonoImage *corlib = mono_defaults.corlib;
8664 mono_image_lock (corlib);
8665 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8666 mono_image_unlock (corlib);
8671 parts = g_strsplit (sigstr, " ", 256);
8680 res = mono_metadata_signature_alloc (corlib, len - 1);
8685 * Under windows, the default pinvoke calling convention is STDCALL but
8688 res->call_convention = MONO_CALL_C;
8691 res->ret = type_from_typename (parts [0]);
8692 for (i = 1; i < len; ++i) {
8693 res->params [i - 1] = type_from_typename (parts [i]);
8698 mono_image_lock (corlib);
8699 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8701 res = res2; /*Value is allocated in the image pool*/
8703 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8704 mono_image_unlock (corlib);
8710 mono_find_jit_icall_by_name (const char *name)
8712 MonoJitICallInfo *info;
8713 g_assert (jit_icall_hash_name);
8716 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8717 mono_icall_unlock ();
8722 mono_find_jit_icall_by_addr (gconstpointer addr)
8724 MonoJitICallInfo *info;
8725 g_assert (jit_icall_hash_addr);
8728 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8729 mono_icall_unlock ();
8735 * mono_get_jit_icall_info:
8737 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8738 * caller should access it while holding the icall lock.
8741 mono_get_jit_icall_info (void)
8743 return jit_icall_hash_name;
8747 * mono_lookup_jit_icall_symbol:
8749 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8752 mono_lookup_jit_icall_symbol (const char *name)
8754 MonoJitICallInfo *info;
8755 const char *res = NULL;
8758 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8760 res = info->c_symbol;
8761 mono_icall_unlock ();
8766 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8769 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8770 mono_icall_unlock ();
8774 * 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
8775 * icalls without wrappers in some cases.
8778 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8780 MonoJitICallInfo *info;
8787 if (!jit_icall_hash_name) {
8788 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8789 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8792 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8793 g_warning ("jit icall already defined \"%s\"\n", name);
8794 g_assert_not_reached ();
8797 info = g_new0 (MonoJitICallInfo, 1);
8802 info->c_symbol = c_symbol;
8803 info->no_raise = no_raise;
8806 info->wrapper = func;
8808 info->wrapper = NULL;
8811 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8812 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8814 mono_icall_unlock ();
8819 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8821 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);