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 (HOST_WIN32)
34 #if defined (HAVE_WCHAR_H)
38 #include "mono/utils/mono-membar.h"
39 #include <mono/metadata/object.h>
40 #include <mono/metadata/threads.h>
41 #include <mono/metadata/threads-types.h>
42 #include <mono/metadata/threadpool-ms.h>
43 #include <mono/metadata/threadpool-ms-io.h>
44 #include <mono/metadata/monitor.h>
45 #include <mono/metadata/reflection.h>
46 #include <mono/metadata/assembly.h>
47 #include <mono/metadata/tabledefs.h>
48 #include <mono/metadata/exception.h>
49 #include <mono/metadata/exception-internals.h>
50 #include <mono/metadata/file-io.h>
51 #include <mono/metadata/console-io.h>
52 #include <mono/metadata/mono-route.h>
53 #include <mono/metadata/socket-io.h>
54 #include <mono/metadata/mono-endian.h>
55 #include <mono/metadata/tokentype.h>
56 #include <mono/metadata/domain-internals.h>
57 #include <mono/metadata/metadata-internals.h>
58 #include <mono/metadata/class-internals.h>
59 #include <mono/metadata/reflection-internals.h>
60 #include <mono/metadata/marshal.h>
61 #include <mono/metadata/gc-internals.h>
62 #include <mono/metadata/mono-gc.h>
63 #include <mono/metadata/rand.h>
64 #include <mono/metadata/sysmath.h>
65 #include <mono/metadata/string-icalls.h>
66 #include <mono/metadata/debug-helpers.h>
67 #include <mono/metadata/process.h>
68 #include <mono/metadata/environment.h>
69 #include <mono/metadata/profiler-private.h>
70 #include <mono/metadata/locales.h>
71 #include <mono/metadata/filewatcher.h>
72 #include <mono/metadata/security.h>
73 #include <mono/metadata/mono-config.h>
74 #include <mono/metadata/cil-coff.h>
75 #include <mono/metadata/number-formatter.h>
76 #include <mono/metadata/security-manager.h>
77 #include <mono/metadata/security-core-clr.h>
78 #include <mono/metadata/mono-perfcounters.h>
79 #include <mono/metadata/mono-debug.h>
80 #include <mono/metadata/mono-ptr-array.h>
81 #include <mono/metadata/verify-internals.h>
82 #include <mono/metadata/runtime.h>
83 #include <mono/metadata/file-mmap.h>
84 #include <mono/metadata/seq-points-data.h>
85 #include <mono/io-layer/io-layer.h>
86 #include <mono/utils/monobitset.h>
87 #include <mono/utils/mono-time.h>
88 #include <mono/utils/mono-proclib.h>
89 #include <mono/utils/mono-string.h>
90 #include <mono/utils/mono-error-internals.h>
91 #include <mono/utils/mono-mmap.h>
92 #include <mono/utils/mono-io-portability.h>
93 #include <mono/utils/mono-digest.h>
94 #include <mono/utils/bsearch.h>
95 #include <mono/utils/mono-os-mutex.h>
96 #include <mono/utils/mono-threads.h>
98 #if defined (HOST_WIN32)
102 #include "decimal-ms.h"
103 #include "number-ms.h"
105 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
106 #include <sys/utsname.h>
109 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
111 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
113 /* Lazy class loading functions */
114 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
115 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
116 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
119 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
122 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
124 static inline MonoBoolean
125 is_generic_parameter (MonoType *type)
127 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
131 mono_class_init_checked (MonoClass *klass, MonoError *error)
133 mono_error_init (error);
135 if (!mono_class_init (klass))
136 mono_error_set_for_class_failure (error, klass);
139 ICALL_EXPORT MonoObject *
140 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
146 MonoObject *result = NULL;
148 ac = (MonoClass *)arr->obj.vtable->klass;
150 esize = mono_array_element_size (ac);
151 ea = (gpointer*)((char*)arr->vector + (pos * esize));
153 if (ac->element_class->valuetype) {
154 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
155 mono_error_set_pending_exception (&error);
157 result = (MonoObject *)*ea;
161 ICALL_EXPORT MonoObject *
162 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
168 MONO_CHECK_ARG_NULL (idxs, NULL);
171 ic = (MonoClass *)io->obj.vtable->klass;
173 ac = (MonoClass *)arr->obj.vtable->klass;
175 g_assert (ic->rank == 1);
176 if (io->bounds != NULL || io->max_length != ac->rank) {
177 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
181 ind = (gint32 *)io->vector;
183 if (arr->bounds == NULL) {
184 if (*ind < 0 || *ind >= arr->max_length) {
185 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
189 return ves_icall_System_Array_GetValueImpl (arr, *ind);
192 for (i = 0; i < ac->rank; i++) {
193 if ((ind [i] < arr->bounds [i].lower_bound) ||
194 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
195 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
200 pos = ind [0] - arr->bounds [0].lower_bound;
201 for (i = 1; i < ac->rank; i++)
202 pos = pos * arr->bounds [i].length + ind [i] -
203 arr->bounds [i].lower_bound;
205 return ves_icall_System_Array_GetValueImpl (arr, pos);
209 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
212 MonoClass *ac, *vc, *ec;
221 mono_error_init (&error);
224 vc = value->vtable->klass;
228 ac = arr->obj.vtable->klass;
229 ec = ac->element_class;
231 esize = mono_array_element_size (ac);
232 ea = (gpointer*)((char*)arr->vector + (pos * esize));
233 va = (gpointer*)((char*)value + sizeof (MonoObject));
235 if (mono_class_is_nullable (ec)) {
236 mono_nullable_init ((guint8*)ea, value, ec);
241 mono_gc_bzero_atomic (ea, esize);
245 #define NO_WIDENING_CONVERSION G_STMT_START{\
246 mono_set_pending_exception (mono_get_exception_argument ( \
247 "value", "not a widening conversion")); \
251 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
252 if (esize < vsize + (extra)) { \
253 mono_set_pending_exception (mono_get_exception_argument ( \
254 "value", "not a widening conversion")); \
259 #define INVALID_CAST G_STMT_START{ \
260 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
261 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
265 /* Check element (destination) type. */
266 switch (ec->byval_arg.type) {
267 case MONO_TYPE_STRING:
268 switch (vc->byval_arg.type) {
269 case MONO_TYPE_STRING:
275 case MONO_TYPE_BOOLEAN:
276 switch (vc->byval_arg.type) {
277 case MONO_TYPE_BOOLEAN:
290 NO_WIDENING_CONVERSION;
299 if (!ec->valuetype) {
300 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
301 if (mono_error_set_pending_exception (&error))
305 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
309 if (mono_object_isinst_checked (value, ec, &error)) {
310 if (ec->has_references)
311 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
313 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
316 if (mono_error_set_pending_exception (&error))
322 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
324 et = ec->byval_arg.type;
325 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
326 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
328 vt = vc->byval_arg.type;
329 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
330 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
332 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
338 case MONO_TYPE_CHAR: \
339 CHECK_WIDENING_CONVERSION(0); \
340 *(etype *) ea = (etype) u64; \
342 /* You can't assign a signed value to an unsigned array. */ \
347 /* You can't assign a floating point number to an integer array. */ \
350 NO_WIDENING_CONVERSION; \
354 #define ASSIGN_SIGNED(etype) G_STMT_START{\
360 CHECK_WIDENING_CONVERSION(0); \
361 *(etype *) ea = (etype) i64; \
363 /* You can assign an unsigned value to a signed array if the array's */ \
364 /* element size is larger than the value size. */ \
369 case MONO_TYPE_CHAR: \
370 CHECK_WIDENING_CONVERSION(1); \
371 *(etype *) ea = (etype) u64; \
373 /* You can't assign a floating point number to an integer array. */ \
376 NO_WIDENING_CONVERSION; \
380 #define ASSIGN_REAL(etype) G_STMT_START{\
384 CHECK_WIDENING_CONVERSION(0); \
385 *(etype *) ea = (etype) r64; \
387 /* All integer values fit into a floating point array, so we don't */ \
388 /* need to CHECK_WIDENING_CONVERSION here. */ \
393 *(etype *) ea = (etype) i64; \
399 case MONO_TYPE_CHAR: \
400 *(etype *) ea = (etype) u64; \
407 u64 = *(guint8 *) va;
410 u64 = *(guint16 *) va;
413 u64 = *(guint32 *) va;
416 u64 = *(guint64 *) va;
422 i64 = *(gint16 *) va;
425 i64 = *(gint32 *) va;
428 i64 = *(gint64 *) va;
431 r64 = *(gfloat *) va;
434 r64 = *(gdouble *) va;
437 u64 = *(guint16 *) va;
439 case MONO_TYPE_BOOLEAN:
440 /* Boolean is only compatible with itself. */
453 NO_WIDENING_CONVERSION;
460 /* If we can't do a direct copy, let's try a widening conversion. */
463 ASSIGN_UNSIGNED (guint16);
465 ASSIGN_UNSIGNED (guint8);
467 ASSIGN_UNSIGNED (guint16);
469 ASSIGN_UNSIGNED (guint32);
471 ASSIGN_UNSIGNED (guint64);
473 ASSIGN_SIGNED (gint8);
475 ASSIGN_SIGNED (gint16);
477 ASSIGN_SIGNED (gint32);
479 ASSIGN_SIGNED (gint64);
481 ASSIGN_REAL (gfloat);
483 ASSIGN_REAL (gdouble);
487 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
491 #undef NO_WIDENING_CONVERSION
492 #undef CHECK_WIDENING_CONVERSION
493 #undef ASSIGN_UNSIGNED
499 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
505 MONO_CHECK_ARG_NULL (idxs,);
507 ic = idxs->obj.vtable->klass;
508 ac = arr->obj.vtable->klass;
510 g_assert (ic->rank == 1);
511 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
512 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
516 ind = (gint32 *)idxs->vector;
518 if (arr->bounds == NULL) {
519 if (*ind < 0 || *ind >= arr->max_length) {
520 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
524 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
528 for (i = 0; i < ac->rank; i++)
529 if ((ind [i] < arr->bounds [i].lower_bound) ||
530 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
531 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
535 pos = ind [0] - arr->bounds [0].lower_bound;
536 for (i = 1; i < ac->rank; i++)
537 pos = pos * arr->bounds [i].length + ind [i] -
538 arr->bounds [i].lower_bound;
540 ves_icall_System_Array_SetValueImpl (arr, value, pos);
543 ICALL_EXPORT MonoArray *
544 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
547 MonoClass *aklass, *klass;
550 gboolean bounded = FALSE;
552 MONO_CHECK_ARG_NULL (type, NULL);
553 MONO_CHECK_ARG_NULL (lengths, NULL);
555 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
557 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
559 for (i = 0; i < mono_array_length (lengths); i++) {
560 if (mono_array_get (lengths, gint32, i) < 0) {
561 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
566 klass = mono_class_from_mono_type (type->type);
567 mono_class_init_checked (klass, &error);
568 if (mono_error_set_pending_exception (&error))
571 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
572 /* vectors are not the same as one dimensional arrays with no-zero bounds */
577 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
579 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
580 for (i = 0; i < aklass->rank; ++i) {
581 sizes [i] = mono_array_get (lengths, guint32, i);
583 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
585 sizes [i + aklass->rank] = 0;
588 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
589 mono_error_set_pending_exception (&error);
594 ICALL_EXPORT MonoArray *
595 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
598 MonoClass *aklass, *klass;
601 gboolean bounded = FALSE;
603 MONO_CHECK_ARG_NULL (type, NULL);
604 MONO_CHECK_ARG_NULL (lengths, NULL);
606 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
608 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
610 for (i = 0; i < mono_array_length (lengths); i++) {
611 if ((mono_array_get (lengths, gint64, i) < 0) ||
612 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
613 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
618 klass = mono_class_from_mono_type (type->type);
619 mono_class_init_checked (klass, &error);
620 if (mono_error_set_pending_exception (&error))
623 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
624 /* vectors are not the same as one dimensional arrays with no-zero bounds */
629 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
631 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
632 for (i = 0; i < aklass->rank; ++i) {
633 sizes [i] = mono_array_get (lengths, guint64, i);
635 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
637 sizes [i + aklass->rank] = 0;
640 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
641 mono_error_set_pending_exception (&error);
647 ves_icall_System_Array_GetRank (MonoObject *arr)
649 return arr->vtable->klass->rank;
653 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
655 gint32 rank = arr->obj.vtable->klass->rank;
658 if ((dimension < 0) || (dimension >= rank)) {
659 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
663 if (arr->bounds == NULL)
664 length = arr->max_length;
666 length = arr->bounds [dimension].length;
668 #ifdef MONO_BIG_ARRAYS
669 if (length > G_MAXINT32) {
670 mono_set_pending_exception (mono_get_exception_overflow ());
678 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
680 gint32 rank = arr->obj.vtable->klass->rank;
682 if ((dimension < 0) || (dimension >= rank)) {
683 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
687 if (arr->bounds == NULL)
688 return arr->max_length;
690 return arr->bounds [dimension].length;
694 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
696 gint32 rank = arr->obj.vtable->klass->rank;
698 if ((dimension < 0) || (dimension >= rank)) {
699 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
703 if (arr->bounds == NULL)
706 return arr->bounds [dimension].lower_bound;
710 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
712 int sz = mono_array_element_size (mono_object_class (arr));
713 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
716 ICALL_EXPORT MonoArray*
717 ves_icall_System_Array_Clone (MonoArray *arr)
720 MonoArray *result = mono_array_clone_checked (arr, &error);
721 mono_error_set_pending_exception (&error);
725 ICALL_EXPORT gboolean
726 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
731 MonoVTable *src_vtable;
732 MonoVTable *dest_vtable;
733 MonoClass *src_class;
734 MonoClass *dest_class;
736 src_vtable = source->obj.vtable;
737 dest_vtable = dest->obj.vtable;
739 if (src_vtable->rank != dest_vtable->rank)
742 if (source->bounds || dest->bounds)
745 /* there's no integer overflow since mono_array_length returns an unsigned integer */
746 if ((dest_idx + length > mono_array_length_fast (dest)) ||
747 (source_idx + length > mono_array_length_fast (source)))
750 src_class = src_vtable->klass->element_class;
751 dest_class = dest_vtable->klass->element_class;
754 * Handle common cases.
757 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
758 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
760 if (src_class == mono_defaults.object_class && dest_class->valuetype)
763 /* Check if we're copying a char[] <==> (u)short[] */
764 if (src_class != dest_class) {
765 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
768 /* 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. */
769 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
773 if (dest_class->valuetype) {
774 element_size = mono_array_element_size (source->obj.vtable->klass);
775 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
776 if (dest_class->has_references) {
777 mono_value_copy_array (dest, dest_idx, source_addr, length);
779 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
780 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
783 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
790 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
796 ac = (MonoClass *)arr->obj.vtable->klass;
798 esize = mono_array_element_size (ac);
799 ea = (gpointer*)((char*)arr->vector + (pos * esize));
801 mono_gc_memmove_atomic (value, ea, esize);
805 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
811 ac = (MonoClass *)arr->obj.vtable->klass;
812 ec = ac->element_class;
814 esize = mono_array_element_size (ac);
815 ea = (gpointer*)((char*)arr->vector + (pos * esize));
817 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
818 g_assert (esize == sizeof (gpointer));
819 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
821 g_assert (ec->inited);
822 g_assert (esize == mono_class_value_size (ec, NULL));
823 if (ec->has_references)
824 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
826 mono_gc_memmove_atomic (ea, value, esize);
831 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
833 MonoClass *klass = array->obj.vtable->klass;
834 guint32 size = mono_array_element_size (klass);
835 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
837 const char *field_data;
839 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
840 MonoException *exc = mono_get_exception_argument("array",
841 "Cannot initialize array of non-primitive type.");
842 mono_set_pending_exception (exc);
846 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
847 MonoException *exc = mono_get_exception_argument("field_handle",
848 "Field doesn't have an RVA");
849 mono_set_pending_exception (exc);
853 size *= array->max_length;
854 field_data = mono_field_get_data (field_handle);
856 if (size > mono_type_size (field_handle->type, &align)) {
857 MonoException *exc = mono_get_exception_argument("field_handle",
858 "Field not large enough to fill array");
859 mono_set_pending_exception (exc);
863 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
865 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
866 guint ## n *src = (guint ## n *) field_data; \
868 nEnt = (size / sizeof(guint ## n)); \
870 for (i = 0; i < nEnt; i++) { \
871 data[i] = read ## n (&src[i]); \
875 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
877 switch (type->type) {
894 memcpy (mono_array_addr (array, char, 0), field_data, size);
898 memcpy (mono_array_addr (array, char, 0), field_data, size);
903 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
905 return offsetof (MonoString, chars);
908 ICALL_EXPORT MonoObject *
909 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
911 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
915 MonoObject *ret = mono_object_clone_checked (obj, &error);
916 mono_error_set_pending_exception (&error);
923 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
929 MONO_CHECK_ARG_NULL (handle,);
931 klass = mono_class_from_mono_type (handle);
932 MONO_CHECK_ARG (handle, klass,);
934 if (klass->generic_container)
937 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
938 if (!is_ok (&error)) {
939 mono_error_set_pending_exception (&error);
943 /* This will call the type constructor */
944 if (!mono_runtime_class_init_full (vtable, &error))
945 mono_error_set_pending_exception (&error);
949 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
953 mono_image_check_for_module_cctor (image);
954 if (image->has_module_cctor) {
955 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
956 if (!mono_error_ok (&error)) {
957 mono_error_set_pending_exception (&error);
960 /*It's fine to raise the exception here*/
961 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
962 if (!is_ok (&error)) {
963 mono_error_set_pending_exception (&error);
966 if (!mono_runtime_class_init_full (vtable, &error))
967 mono_error_set_pending_exception (&error);
971 ICALL_EXPORT MonoBoolean
972 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
977 /* later make this configurable and per-arch */
978 int min_size = 4096 * 4 * sizeof (void*);
979 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
980 /* if we have no info we are optimistic and assume there is enough room */
984 // FIXME: Windows dynamically extends the stack, so stack_addr might be close
988 current = (guint8 *)&stack_addr;
989 if (current > stack_addr) {
990 if ((current - stack_addr) < min_size)
993 if (current - (stack_addr - stack_size) < min_size)
999 ICALL_EXPORT MonoObject *
1000 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1003 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1004 mono_error_set_pending_exception (&error);
1010 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1014 MonoObject **values = NULL;
1017 gint32 result = (int)(gsize)mono_defaults.int32_class;
1018 MonoClassField* field;
1021 klass = mono_object_class (this_obj);
1023 if (mono_class_num_fields (klass) == 0)
1027 * Compute the starting value of the hashcode for fields of primitive
1028 * types, and return the remaining fields in an array to the managed side.
1029 * This way, we can avoid costly reflection operations in managed code.
1032 while ((field = mono_class_get_fields (klass, &iter))) {
1033 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1035 if (mono_field_is_deleted (field))
1037 /* FIXME: Add more types */
1038 switch (field->type->type) {
1040 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1042 case MONO_TYPE_STRING: {
1044 s = *(MonoString**)((guint8*)this_obj + field->offset);
1046 result ^= mono_string_hash (s);
1051 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1052 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1053 if (!is_ok (&error)) {
1054 mono_error_set_pending_exception (&error);
1057 values [count++] = o;
1063 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1064 if (mono_error_set_pending_exception (&error))
1066 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1067 for (i = 0; i < count; ++i)
1068 mono_array_setref (*fields, i, values [i]);
1075 ICALL_EXPORT MonoBoolean
1076 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1080 MonoObject **values = NULL;
1082 MonoClassField* field;
1086 MONO_CHECK_ARG_NULL (that, FALSE);
1088 if (this_obj->vtable != that->vtable)
1091 klass = mono_object_class (this_obj);
1093 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1094 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1097 * Do the comparison for fields of primitive type and return a result if
1098 * possible. Otherwise, return the remaining fields in an array to the
1099 * managed side. This way, we can avoid costly reflection operations in
1104 while ((field = mono_class_get_fields (klass, &iter))) {
1105 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1107 if (mono_field_is_deleted (field))
1109 /* FIXME: Add more types */
1110 switch (field->type->type) {
1113 case MONO_TYPE_BOOLEAN:
1114 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1119 case MONO_TYPE_CHAR:
1120 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1125 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1130 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1134 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1138 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1143 case MONO_TYPE_STRING: {
1144 MonoString *s1, *s2;
1145 guint32 s1len, s2len;
1146 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1147 s2 = *(MonoString**)((guint8*)that + field->offset);
1150 if ((s1 == NULL) || (s2 == NULL))
1152 s1len = mono_string_length (s1);
1153 s2len = mono_string_length (s2);
1157 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1163 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1164 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1165 if (!is_ok (&error)) {
1166 mono_error_set_pending_exception (&error);
1169 values [count++] = o;
1170 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1171 if (!is_ok (&error)) {
1172 mono_error_set_pending_exception (&error);
1175 values [count++] = o;
1178 if (klass->enumtype)
1179 /* enums only have one non-static field */
1185 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1186 if (mono_error_set_pending_exception (&error))
1188 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1189 for (i = 0; i < count; ++i)
1190 mono_array_setref_fast (*fields, i, values [i]);
1197 ICALL_EXPORT MonoReflectionType *
1198 ves_icall_System_Object_GetType (MonoObject *obj)
1201 MonoReflectionType *ret;
1202 #ifndef DISABLE_REMOTING
1203 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1204 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1207 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1209 mono_error_set_pending_exception (&error);
1214 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
1216 MONO_CHECK_ARG_NULL (obj, 0);
1219 gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
1220 mono_error_set_pending_exception (&error);
1225 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1226 MonoReflectionMethod *method,
1227 MonoArray *opt_param_types)
1229 MONO_CHECK_ARG_NULL (method, 0);
1232 gint32 result = mono_image_create_method_token (
1233 mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
1234 mono_error_set_pending_exception (&error);
1239 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1242 mono_image_create_pefile (mb, file, &error);
1243 mono_error_set_pending_exception (&error);
1247 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1250 mono_image_build_metadata (mb, &error);
1251 mono_error_set_pending_exception (&error);
1255 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
1257 mono_image_register_token (mb->dynamic_image, token, obj);
1260 ICALL_EXPORT MonoObject*
1261 ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
1265 mono_loader_lock ();
1266 obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
1267 mono_loader_unlock ();
1272 ICALL_EXPORT MonoReflectionModule*
1273 ves_icall_System_Reflection_Emit_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
1276 MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
1277 mono_error_set_pending_exception (&error);
1282 * ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class:
1283 * @tb: a TypeBuilder object
1286 * Creates the generic class after all generic parameters have been added.
1289 ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
1292 (void) mono_reflection_create_generic_class (tb, &error);
1293 mono_error_set_pending_exception (&error);
1296 #ifndef DISABLE_REFLECTION_EMIT
1297 ICALL_EXPORT MonoArray*
1298 ves_icall_System_Reflection_Emit_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
1301 MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
1302 mono_error_set_pending_exception (&error);
1308 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1310 MonoMethod **dest = (MonoMethod **)data;
1312 /* skip unmanaged frames */
1317 if (!strcmp (m->klass->name_space, "System.Reflection"))
1326 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1328 MonoMethod **dest = (MonoMethod **)data;
1330 /* skip unmanaged frames */
1334 if (m->wrapper_type != MONO_WRAPPER_NONE)
1342 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1353 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1355 MonoMethod **dest = (MonoMethod **)data;
1357 /* skip unmanaged frames */
1361 if (m->wrapper_type != MONO_WRAPPER_NONE)
1369 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1370 || (!strcmp (m->klass->name_space, "System"))))
1380 static MonoReflectionType *
1381 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoError *error)
1383 MonoMethod *m, *dest;
1385 MonoType *type = NULL;
1386 MonoAssembly *assembly = NULL;
1387 gboolean type_resolve = FALSE;
1388 MonoImage *rootimage = NULL;
1390 mono_error_init (error);
1393 * We must compute the calling assembly as type loading must happen under a metadata context.
1394 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1395 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1397 m = mono_method_get_last_managed ();
1399 if (m && m->klass->image != mono_defaults.corlib) {
1400 /* Happens with inlining */
1402 /* Ugly hack: type_from_parsed_name is called from
1403 * System.Type.internal_from_name, which is called most
1404 * directly from System.Type.GetType(string,bool,bool) but
1405 * also indirectly from places such as
1406 * System.Type.GetType(string,func,func) (via
1407 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1408 * so we need to skip over all of those to find the true caller.
1410 * It would be nice if we had stack marks.
1412 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1418 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1419 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1420 * to crash. This only seems to happen in some strange remoting
1421 * scenarios and I was unable to figure out what's happening there.
1422 * Dec 10, 2005 - Martin.
1426 assembly = dest->klass->image->assembly;
1427 type_resolve = TRUE;
1428 rootimage = assembly->image;
1430 g_warning (G_STRLOC);
1433 if (info->assembly.name)
1434 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1437 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1438 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1439 return_val_if_nok (error, NULL);
1443 // Say we're looking for System.Generic.Dict<int, Local>
1444 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1445 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1446 // is messed up when we go to construct the Local as the type arg...
1448 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1449 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1450 if (!info->assembly.name && !type) {
1452 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1453 return_val_if_nok (error, NULL);
1455 if (assembly && !type && type_resolve) {
1456 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1457 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1458 return_val_if_nok (error, NULL);
1464 return mono_type_get_object_checked (mono_domain_get (), type, error);
1467 ICALL_EXPORT MonoReflectionType*
1468 ves_icall_System_Type_internal_from_name (MonoString *name,
1469 MonoBoolean throwOnError,
1470 MonoBoolean ignoreCase)
1473 MonoTypeNameParse info;
1474 MonoReflectionType *type = NULL;
1477 char *str = mono_string_to_utf8_checked (name, &error);
1478 if (!is_ok (&error))
1481 parsedOk = mono_reflection_parse_type (str, &info);
1483 /* mono_reflection_parse_type() mangles the string */
1485 mono_reflection_free_type_info (&info);
1487 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1491 type = type_from_parsed_name (&info, ignoreCase, &error);
1493 mono_reflection_free_type_info (&info);
1495 if (!is_ok (&error))
1500 mono_error_set_type_load_name (&error, g_strdup (str), NULL, "");
1507 if (!is_ok (&error)) {
1509 mono_error_set_pending_exception (&error);
1511 mono_error_cleanup (&error);
1519 ICALL_EXPORT MonoReflectionType*
1520 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1523 MonoReflectionType *ret;
1524 MonoDomain *domain = mono_domain_get ();
1526 ret = mono_type_get_object_checked (domain, handle, &error);
1527 mono_error_set_pending_exception (&error);
1532 ICALL_EXPORT MonoType*
1533 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1535 return mono_class_get_type (klass);
1539 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1541 g_ptr_array_free (ptr_array, TRUE);
1545 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1551 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1554 char *res = mono_string_to_utf8_checked (s, &error);
1555 mono_error_set_pending_exception (&error);
1559 /* System.TypeCode */
1578 TYPECODE_STRING = 18
1581 ICALL_EXPORT guint32
1582 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1584 int t = type->type->type;
1586 if (type->type->byref)
1587 return TYPECODE_OBJECT;
1591 case MONO_TYPE_VOID:
1592 return TYPECODE_OBJECT;
1593 case MONO_TYPE_BOOLEAN:
1594 return TYPECODE_BOOLEAN;
1596 return TYPECODE_BYTE;
1598 return TYPECODE_SBYTE;
1600 return TYPECODE_UINT16;
1602 return TYPECODE_INT16;
1603 case MONO_TYPE_CHAR:
1604 return TYPECODE_CHAR;
1608 return TYPECODE_OBJECT;
1610 return TYPECODE_UINT32;
1612 return TYPECODE_INT32;
1614 return TYPECODE_UINT64;
1616 return TYPECODE_INT64;
1618 return TYPECODE_SINGLE;
1620 return TYPECODE_DOUBLE;
1621 case MONO_TYPE_VALUETYPE: {
1622 MonoClass *klass = type->type->data.klass;
1624 if (klass->enumtype) {
1625 t = mono_class_enum_basetype (klass)->type;
1627 } else if (mono_is_corlib_image (klass->image)) {
1628 if (strcmp (klass->name_space, "System") == 0) {
1629 if (strcmp (klass->name, "Decimal") == 0)
1630 return TYPECODE_DECIMAL;
1631 else if (strcmp (klass->name, "DateTime") == 0)
1632 return TYPECODE_DATETIME;
1635 return TYPECODE_OBJECT;
1637 case MONO_TYPE_STRING:
1638 return TYPECODE_STRING;
1639 case MONO_TYPE_SZARRAY:
1640 case MONO_TYPE_ARRAY:
1641 case MONO_TYPE_OBJECT:
1643 case MONO_TYPE_MVAR:
1644 case MONO_TYPE_TYPEDBYREF:
1645 return TYPECODE_OBJECT;
1646 case MONO_TYPE_CLASS:
1648 MonoClass *klass = type->type->data.klass;
1649 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1650 if (strcmp (klass->name, "DBNull") == 0)
1651 return TYPECODE_DBNULL;
1654 return TYPECODE_OBJECT;
1655 case MONO_TYPE_GENERICINST:
1656 return TYPECODE_OBJECT;
1658 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1664 mono_type_is_primitive (MonoType *type)
1666 return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) ||
1667 type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U;
1671 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1673 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1674 return mono_class_enum_basetype (type->data.klass);
1675 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1676 return mono_class_enum_basetype (type->data.generic_class->container_class);
1680 ICALL_EXPORT guint32
1681 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1686 g_assert (type != NULL);
1688 klass = mono_class_from_mono_type (type->type);
1689 klassc = mono_class_from_mono_type (c->type);
1691 if (type->type->byref ^ c->type->byref)
1694 if (type->type->byref) {
1695 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1696 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1698 klass = mono_class_from_mono_type (t);
1699 klassc = mono_class_from_mono_type (ot);
1701 if (mono_type_is_primitive (t)) {
1702 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1703 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1704 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1705 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1706 return t->type == ot->type;
1708 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1711 if (klass->valuetype)
1712 return klass == klassc;
1713 return klass->valuetype == klassc->valuetype;
1716 return mono_class_is_assignable_from (klass, klassc);
1719 ICALL_EXPORT guint32
1720 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1723 MonoClass *klass = mono_class_from_mono_type (type->type);
1724 mono_class_init_checked (klass, &error);
1725 if (!is_ok (&error)) {
1726 mono_error_set_pending_exception (&error);
1729 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1730 mono_error_set_pending_exception (&error);
1734 ICALL_EXPORT guint32
1735 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1737 MonoClass *klass = mono_class_from_mono_type (type->type);
1738 return klass->flags;
1741 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1742 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1745 MonoClass *klass = field->field->parent;
1746 MonoMarshalType *info;
1750 if (klass->generic_container ||
1751 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1754 ftype = mono_field_get_type (field->field);
1755 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1758 info = mono_marshal_load_type_info (klass);
1760 for (i = 0; i < info->num_fields; ++i) {
1761 if (info->fields [i].field == field->field) {
1762 if (!info->fields [i].mspec)
1765 MonoReflectionMarshalAsAttribute* obj;
1766 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1767 if (!mono_error_ok (&error))
1768 mono_error_set_pending_exception (&error);
1777 ICALL_EXPORT MonoReflectionField*
1778 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1781 gboolean found = FALSE;
1787 klass = handle->parent;
1789 klass = mono_class_from_mono_type (type);
1791 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1794 /* The managed code will throw the exception */
1798 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1799 mono_error_set_pending_exception (&error);
1803 ICALL_EXPORT MonoReflectionEvent*
1804 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1812 klass = handle->parent;
1814 klass = mono_class_from_mono_type (type);
1816 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1818 /* Managed code will throw an exception */
1822 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1823 mono_error_set_pending_exception (&error);
1828 ICALL_EXPORT MonoReflectionProperty*
1829 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1837 klass = handle->parent;
1839 klass = mono_class_from_mono_type (type);
1841 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1843 /* Managed code will throw an exception */
1847 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1848 mono_error_set_pending_exception (&error);
1852 ICALL_EXPORT MonoArray*
1853 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1856 MonoType *type = mono_field_get_type_checked (field->field, &error);
1859 if (!mono_error_ok (&error)) {
1860 mono_error_set_pending_exception (&error);
1864 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1865 mono_error_set_pending_exception (&error);
1870 vell_icall_get_method_attributes (MonoMethod *method)
1872 return method->flags;
1876 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1879 MonoReflectionType *rt;
1880 MonoDomain *domain = mono_domain_get ();
1881 MonoMethodSignature* sig;
1883 sig = mono_method_signature_checked (method, &error);
1884 if (!mono_error_ok (&error)) {
1885 mono_error_set_pending_exception (&error);
1889 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1890 if (!mono_error_ok (&error)) {
1891 mono_error_set_pending_exception (&error);
1895 MONO_STRUCT_SETREF (info, parent, rt);
1897 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1898 if (!mono_error_ok (&error)) {
1899 mono_error_set_pending_exception (&error);
1903 MONO_STRUCT_SETREF (info, ret, rt);
1905 info->attrs = method->flags;
1906 info->implattrs = method->iflags;
1907 if (sig->call_convention == MONO_CALL_DEFAULT)
1908 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1910 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1915 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1918 ICALL_EXPORT MonoArray*
1919 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1922 MonoDomain *domain = mono_domain_get ();
1924 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1925 mono_error_set_pending_exception (&error);
1929 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1930 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1933 MonoDomain *domain = mono_domain_get ();
1934 MonoReflectionMarshalAsAttribute* res = NULL;
1935 MonoMarshalSpec **mspecs;
1938 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1939 mono_method_get_marshal_info (method, mspecs);
1942 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1943 if (!mono_error_ok (&error)) {
1944 mono_error_set_pending_exception (&error);
1949 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1951 mono_metadata_free_marshal_spec (mspecs [i]);
1958 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1960 MonoClass *parent = field->field->parent;
1961 if (!parent->size_inited)
1962 mono_class_init (parent);
1963 mono_class_setup_fields_locking (parent);
1965 return field->field->offset - sizeof (MonoObject);
1968 ICALL_EXPORT MonoReflectionType*
1969 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1972 MonoReflectionType *ret;
1975 parent = declaring? field->field->parent: field->klass;
1977 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1978 mono_error_set_pending_exception (&error);
1984 ICALL_EXPORT MonoObject *
1985 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1988 MonoClass *fklass = field->klass;
1989 MonoClassField *cf = field->field;
1990 MonoDomain *domain = mono_object_domain (field);
1992 if (fklass->image->assembly->ref_only) {
1993 mono_set_pending_exception (mono_get_exception_invalid_operation (
1994 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1998 if (mono_security_core_clr_enabled () &&
1999 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
2000 mono_error_set_pending_exception (&error);
2004 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
2005 mono_error_set_pending_exception (&error);
2010 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
2013 MonoClassField *cf = field->field;
2017 if (field->klass->image->assembly->ref_only) {
2018 mono_set_pending_exception (mono_get_exception_invalid_operation (
2019 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
2023 if (mono_security_core_clr_enabled () &&
2024 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
2025 mono_error_set_pending_exception (&error);
2029 type = mono_field_get_type_checked (cf, &error);
2030 if (!mono_error_ok (&error)) {
2031 mono_error_set_pending_exception (&error);
2035 v = (gchar *) value;
2037 switch (type->type) {
2040 case MONO_TYPE_BOOLEAN:
2043 case MONO_TYPE_CHAR:
2052 case MONO_TYPE_VALUETYPE:
2055 v += sizeof (MonoObject);
2057 case MONO_TYPE_STRING:
2058 case MONO_TYPE_OBJECT:
2059 case MONO_TYPE_CLASS:
2060 case MONO_TYPE_ARRAY:
2061 case MONO_TYPE_SZARRAY:
2064 case MONO_TYPE_GENERICINST: {
2065 MonoGenericClass *gclass = type->data.generic_class;
2066 g_assert (!gclass->context.class_inst->is_open);
2068 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
2069 MonoClass *nklass = mono_class_from_mono_type (type);
2070 MonoObject *nullable;
2073 * Convert the boxed vtype into a Nullable structure.
2074 * This is complicated by the fact that Nullables have
2075 * a variable structure.
2077 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2078 if (!mono_error_ok (&error)) {
2079 mono_error_set_pending_exception (&error);
2083 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2085 v = (gchar *)mono_object_unbox (nullable);
2088 if (gclass->container_class->valuetype && (v != NULL))
2089 v += sizeof (MonoObject);
2093 g_error ("type 0x%x not handled in "
2094 "ves_icall_FieldInfo_SetValueInternal", type->type);
2099 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2100 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2101 if (!is_ok (&error)) {
2102 mono_error_set_pending_exception (&error);
2105 if (!vtable->initialized) {
2106 if (!mono_runtime_class_init_full (vtable, &error)) {
2107 mono_error_set_pending_exception (&error);
2111 mono_field_static_set_value (vtable, cf, v);
2113 mono_field_set_value (obj, cf, v);
2118 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2127 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2128 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2132 if (MONO_TYPE_IS_REFERENCE (f->type))
2133 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2135 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2138 ICALL_EXPORT MonoObject *
2139 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2141 MonoObject *o = NULL;
2142 MonoClassField *field = rfield->field;
2144 MonoDomain *domain = mono_object_domain (rfield);
2146 MonoTypeEnum def_type;
2147 const char *def_value;
2151 mono_class_init (field->parent);
2153 t = mono_field_get_type_checked (field, &error);
2154 if (!mono_error_ok (&error)) {
2155 mono_error_set_pending_exception (&error);
2159 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2160 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2164 if (image_is_dynamic (field->parent->image)) {
2165 MonoClass *klass = field->parent;
2166 int fidx = field - klass->fields;
2168 g_assert (fidx >= 0 && fidx < klass->field.count);
2169 g_assert (klass->ext);
2170 g_assert (klass->ext->field_def_values);
2171 def_type = klass->ext->field_def_values [fidx].def_type;
2172 def_value = klass->ext->field_def_values [fidx].data;
2173 if (def_type == MONO_TYPE_END) {
2174 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2178 def_value = mono_class_get_field_default_value (field, &def_type);
2179 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2181 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2186 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2190 case MONO_TYPE_BOOLEAN:
2193 case MONO_TYPE_CHAR:
2201 case MONO_TYPE_R8: {
2204 /* boxed value type */
2205 t = g_new0 (MonoType, 1);
2207 klass = mono_class_from_mono_type (t);
2209 o = mono_object_new_checked (domain, klass, &error);
2210 if (!mono_error_ok (&error)) {
2211 mono_error_set_pending_exception (&error);
2214 v = ((gchar *) o) + sizeof (MonoObject);
2215 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2216 if (mono_error_set_pending_exception (&error))
2220 case MONO_TYPE_STRING:
2221 case MONO_TYPE_CLASS:
2222 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2223 if (mono_error_set_pending_exception (&error))
2227 g_assert_not_reached ();
2233 ICALL_EXPORT MonoReflectionType*
2234 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2237 MonoReflectionType *ret;
2240 type = mono_field_get_type_checked (ref_field->field, &error);
2241 if (!mono_error_ok (&error)) {
2242 mono_error_set_pending_exception (&error);
2246 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2247 if (!mono_error_ok (&error)) {
2248 mono_error_set_pending_exception (&error);
2255 /* From MonoProperty.cs */
2257 PInfo_Attributes = 1,
2258 PInfo_GetMethod = 1 << 1,
2259 PInfo_SetMethod = 1 << 2,
2260 PInfo_ReflectedType = 1 << 3,
2261 PInfo_DeclaringType = 1 << 4,
2266 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2269 MonoReflectionType *rt;
2270 MonoReflectionMethod *rm;
2271 MonoDomain *domain = mono_object_domain (property);
2272 const MonoProperty *pproperty = property->property;
2274 if ((req_info & PInfo_ReflectedType) != 0) {
2275 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2276 if (mono_error_set_pending_exception (&error))
2279 MONO_STRUCT_SETREF (info, parent, rt);
2281 if ((req_info & PInfo_DeclaringType) != 0) {
2282 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2283 if (mono_error_set_pending_exception (&error))
2286 MONO_STRUCT_SETREF (info, declaring_type, rt);
2289 if ((req_info & PInfo_Name) != 0)
2290 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2292 if ((req_info & PInfo_Attributes) != 0)
2293 info->attrs = pproperty->attrs;
2295 if ((req_info & PInfo_GetMethod) != 0) {
2296 if (pproperty->get &&
2297 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2298 pproperty->get->klass == property->klass)) {
2299 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2300 if (mono_error_set_pending_exception (&error))
2306 MONO_STRUCT_SETREF (info, get, rm);
2308 if ((req_info & PInfo_SetMethod) != 0) {
2309 if (pproperty->set &&
2310 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2311 pproperty->set->klass == property->klass)) {
2312 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2313 if (mono_error_set_pending_exception (&error))
2319 MONO_STRUCT_SETREF (info, set, rm);
2322 * There may be other methods defined for properties, though, it seems they are not exposed
2323 * in the reflection API
2328 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2331 MonoReflectionType *rt;
2332 MonoReflectionMethod *rm;
2333 MonoDomain *domain = mono_object_domain (event);
2335 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2336 if (mono_error_set_pending_exception (&error))
2339 MONO_STRUCT_SETREF (info, reflected_type, rt);
2341 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2342 if (mono_error_set_pending_exception (&error))
2345 MONO_STRUCT_SETREF (info, declaring_type, rt);
2347 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2348 info->attrs = event->event->attrs;
2350 if (event->event->add) {
2351 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2352 if (mono_error_set_pending_exception (&error))
2358 MONO_STRUCT_SETREF (info, add_method, rm);
2360 if (event->event->remove) {
2361 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2362 if (mono_error_set_pending_exception (&error))
2368 MONO_STRUCT_SETREF (info, remove_method, rm);
2370 if (event->event->raise) {
2371 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2372 if (mono_error_set_pending_exception (&error))
2378 MONO_STRUCT_SETREF (info, raise_method, rm);
2380 #ifndef MONO_SMALL_CONFIG
2381 if (event->event->other) {
2383 while (event->event->other [n])
2385 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2386 if (mono_error_set_pending_exception (&error))
2388 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2390 for (i = 0; i < n; i++) {
2391 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2392 if (mono_error_set_pending_exception (&error))
2394 mono_array_setref (info->other_methods, i, rm);
2401 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2406 mono_class_setup_interfaces (klass, error);
2407 if (!mono_error_ok (error))
2410 for (i = 0; i < klass->interface_count; i++) {
2411 ic = klass->interfaces [i];
2412 g_hash_table_insert (ifaces, ic, ic);
2414 collect_interfaces (ic, ifaces, error);
2415 if (!mono_error_ok (error))
2421 MonoArray *iface_array;
2422 MonoGenericContext *context;
2426 } FillIfaceArrayData;
2429 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2431 MonoReflectionType *rt;
2432 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2433 MonoClass *ic = (MonoClass *)key;
2434 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2436 if (!mono_error_ok (data->error))
2439 if (data->context && ic->generic_class && ic->generic_class->context.class_inst->is_open) {
2440 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2441 if (!mono_error_ok (data->error))
2445 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2446 if (!mono_error_ok (data->error))
2449 mono_array_setref (data->iface_array, data->next_idx++, rt);
2452 mono_metadata_free_type (inflated);
2456 get_interfaces_hash (gconstpointer v1)
2458 MonoClass *k = (MonoClass*)v1;
2460 return k->type_token;
2463 ICALL_EXPORT MonoArray*
2464 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2467 MonoClass *klass = mono_class_from_mono_type (type->type);
2469 FillIfaceArrayData data = { 0 };
2472 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2474 if (klass->generic_class && klass->generic_class->context.class_inst->is_open) {
2475 data.context = mono_class_get_context (klass);
2476 klass = klass->generic_class->container_class;
2479 for (parent = klass; parent; parent = parent->parent) {
2480 mono_class_setup_interfaces (parent, &error);
2481 if (!mono_error_ok (&error))
2483 collect_interfaces (parent, iface_hash, &error);
2484 if (!mono_error_ok (&error))
2488 data.error = &error;
2489 data.domain = mono_object_domain (type);
2491 len = g_hash_table_size (iface_hash);
2493 g_hash_table_destroy (iface_hash);
2494 if (!data.domain->empty_types) {
2495 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2496 if (!is_ok (&error))
2499 return data.domain->empty_types;
2502 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2503 if (!is_ok (&error))
2505 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2506 if (!mono_error_ok (&error))
2509 g_hash_table_destroy (iface_hash);
2510 return data.iface_array;
2513 g_hash_table_destroy (iface_hash);
2514 mono_error_set_pending_exception (&error);
2519 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2521 gboolean variance_used;
2522 MonoClass *klass = mono_class_from_mono_type (type->type);
2523 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2524 MonoReflectionMethod *member;
2527 int i = 0, len, ioffset;
2531 mono_class_init_checked (klass, &error);
2532 if (mono_error_set_pending_exception (&error))
2534 mono_class_init_checked (iclass, &error);
2535 if (mono_error_set_pending_exception (&error))
2538 mono_class_setup_vtable (klass);
2540 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2544 len = mono_class_num_methods (iclass);
2545 domain = mono_object_domain (type);
2546 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2547 if (mono_error_set_pending_exception (&error))
2549 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2550 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2551 if (mono_error_set_pending_exception (&error))
2553 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2555 while ((method = mono_class_get_methods (iclass, &iter))) {
2556 member = mono_method_get_object_checked (domain, method, iclass, &error);
2557 if (mono_error_set_pending_exception (&error))
2559 mono_array_setref (*methods, i, member);
2560 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2561 if (mono_error_set_pending_exception (&error))
2563 mono_array_setref (*targets, i, member);
2570 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2573 MonoClass *klass = mono_class_from_mono_type (type->type);
2575 mono_class_init_checked (klass, &error);
2576 if (mono_error_set_pending_exception (&error))
2579 if (image_is_dynamic (klass->image)) {
2580 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2581 *packing = tb->packing_size;
2582 *size = tb->class_size;
2584 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2588 ICALL_EXPORT MonoReflectionType*
2589 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2592 MonoReflectionType *ret;
2595 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2596 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2597 mono_error_set_pending_exception (&error);
2601 klass = mono_class_from_mono_type (type->type);
2602 mono_class_init_checked (klass, &error);
2603 if (mono_error_set_pending_exception (&error))
2607 // GetElementType should only return a type for:
2608 // Array Pointer PassedByRef
2609 if (type->type->byref)
2610 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2611 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2612 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2613 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2614 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2618 mono_error_set_pending_exception (&error);
2623 ICALL_EXPORT MonoReflectionType*
2624 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2627 MonoReflectionType *ret;
2629 if (type->type->byref)
2632 MonoClass *klass = mono_class_from_mono_type (type->type);
2636 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2637 mono_error_set_pending_exception (&error);
2642 ICALL_EXPORT MonoBoolean
2643 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2645 return type->type->type == MONO_TYPE_PTR;
2648 ICALL_EXPORT MonoBoolean
2649 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2651 return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
2654 ICALL_EXPORT MonoBoolean
2655 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2657 return type->type->byref;
2660 ICALL_EXPORT MonoBoolean
2661 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2664 MonoClass *klass = mono_class_from_mono_type (type->type);
2665 mono_class_init_checked (klass, &error);
2666 if (mono_error_set_pending_exception (&error))
2669 return mono_class_is_com_object (klass);
2672 ICALL_EXPORT guint32
2673 ves_icall_reflection_get_token (MonoObject* obj)
2676 guint32 result = mono_reflection_get_token_checked (obj, &error);
2677 mono_error_set_pending_exception (&error);
2681 ICALL_EXPORT MonoReflectionModule*
2682 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2685 MonoReflectionModule *result = NULL;
2686 MonoClass *klass = mono_class_from_mono_type (type->type);
2687 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2688 mono_error_set_pending_exception (&error);
2692 ICALL_EXPORT MonoReflectionAssembly*
2693 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2696 MonoDomain *domain = mono_domain_get ();
2697 MonoClass *klass = mono_class_from_mono_type (type->type);
2698 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2699 mono_error_set_pending_exception (&error);
2703 ICALL_EXPORT MonoReflectionType*
2704 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2707 MonoReflectionType *ret;
2708 MonoDomain *domain = mono_domain_get ();
2711 if (type->type->byref)
2713 if (type->type->type == MONO_TYPE_VAR) {
2714 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2715 klass = param ? param->owner.klass : NULL;
2716 } else if (type->type->type == MONO_TYPE_MVAR) {
2717 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2718 klass = param ? param->owner.method->klass : NULL;
2720 klass = mono_class_from_mono_type (type->type)->nested_in;
2726 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2727 mono_error_set_pending_exception (&error);
2732 ICALL_EXPORT MonoString*
2733 ves_icall_RuntimeType_get_Name (MonoReflectionType *type)
2735 MonoDomain *domain = mono_domain_get ();
2736 MonoClass *klass = mono_class_from_mono_type (type->type);
2738 if (type->type->byref) {
2739 char *n = g_strdup_printf ("%s&", klass->name);
2740 MonoString *res = mono_string_new (domain, n);
2746 return mono_string_new (domain, klass->name);
2750 ICALL_EXPORT MonoString*
2751 ves_icall_RuntimeType_get_Namespace (MonoReflectionType *type)
2753 MonoDomain *domain = mono_domain_get ();
2754 MonoClass *klass = mono_class_from_mono_type (type->type);
2756 while (klass->nested_in)
2757 klass = klass->nested_in;
2759 if (klass->name_space [0] == '\0')
2762 return mono_string_new (domain, klass->name_space);
2766 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2770 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2771 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2775 klass = mono_class_from_mono_type (type->type);
2781 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2783 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2786 ICALL_EXPORT MonoArray*
2787 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2790 MonoReflectionType *rt;
2792 MonoClass *klass, *pklass;
2793 MonoDomain *domain = mono_object_domain (type);
2796 klass = mono_class_from_mono_type (type->type);
2798 if (klass->generic_container) {
2799 MonoGenericContainer *container = klass->generic_container;
2800 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2801 if (mono_error_set_pending_exception (&error))
2803 for (i = 0; i < container->type_argc; ++i) {
2804 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2806 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2807 if (mono_error_set_pending_exception (&error))
2810 mono_array_setref (res, i, rt);
2812 } else if (klass->generic_class) {
2813 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2814 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2815 if (mono_error_set_pending_exception (&error))
2817 for (i = 0; i < inst->type_argc; ++i) {
2818 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2819 if (mono_error_set_pending_exception (&error))
2822 mono_array_setref (res, i, rt);
2830 ICALL_EXPORT gboolean
2831 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2835 if (!IS_MONOTYPE (type))
2838 if (type->type->byref)
2841 klass = mono_class_from_mono_type (type->type);
2842 return klass->generic_container != NULL;
2845 ICALL_EXPORT MonoReflectionType*
2846 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2849 MonoReflectionType *ret;
2852 if (type->type->byref)
2855 klass = mono_class_from_mono_type (type->type);
2857 if (klass->generic_container) {
2858 return type; /* check this one */
2860 if (klass->generic_class) {
2861 MonoClass *generic_class = klass->generic_class->container_class;
2864 tb = mono_class_get_ref_info (generic_class);
2866 if (generic_class->wastypebuilder && tb)
2867 return (MonoReflectionType *)tb;
2869 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2870 mono_error_set_pending_exception (&error);
2878 ICALL_EXPORT MonoReflectionType*
2879 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2882 MonoReflectionType *ret;
2884 MonoType *geninst, **types;
2887 g_assert (IS_MONOTYPE (type));
2888 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2889 if (mono_error_set_pending_exception (&error))
2892 count = mono_array_length (type_array);
2893 types = g_new0 (MonoType *, count);
2895 for (i = 0; i < count; i++) {
2896 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2897 types [i] = t->type;
2900 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2903 mono_error_set_pending_exception (&error);
2907 klass = mono_class_from_mono_type (geninst);
2909 /*we might inflate to the GTD*/
2910 if (klass->generic_class && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2911 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2915 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2916 mono_error_set_pending_exception (&error);
2921 ICALL_EXPORT gboolean
2922 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2926 if (!IS_MONOTYPE (type))
2929 if (type->type->byref)
2932 klass = mono_class_from_mono_type (type->type);
2933 return klass->generic_class != NULL || klass->generic_container != NULL;
2937 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2939 if (!IS_MONOTYPE (type))
2942 if (is_generic_parameter (type->type))
2943 return mono_type_get_generic_param_num (type->type);
2947 ICALL_EXPORT MonoGenericParamInfo *
2948 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2950 return mono_generic_param_info (type->type->data.generic_param);
2953 ICALL_EXPORT MonoBoolean
2954 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2956 return is_generic_parameter (type->type);
2959 ICALL_EXPORT MonoBoolean
2960 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2962 return is_generic_parameter (tb->type.type);
2966 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2967 MonoReflectionType *t)
2969 enumtype->type = t->type;
2972 ICALL_EXPORT MonoReflectionMethod*
2973 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2974 MonoReflectionMethod* generic)
2981 MonoReflectionMethod *ret = NULL;
2983 domain = ((MonoObject *)type)->vtable->domain;
2985 klass = mono_class_from_mono_type (type->type);
2986 mono_class_init_checked (klass, &error);
2987 if (mono_error_set_pending_exception (&error))
2991 while ((method = mono_class_get_methods (klass, &iter))) {
2992 if (method->token == generic->method->token) {
2993 ret = mono_method_get_object_checked (domain, method, klass, &error);
2994 if (mono_error_set_pending_exception (&error))
3002 ICALL_EXPORT MonoReflectionMethod *
3003 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
3006 MonoType *type = ref_type->type;
3008 MonoReflectionMethod *ret = NULL;
3010 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
3011 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
3014 if (type->type == MONO_TYPE_VAR)
3017 method = mono_type_get_generic_param_owner (type)->owner.method;
3020 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
3021 if (!mono_error_ok (&error))
3022 mono_set_pending_exception (mono_error_convert_to_exception (&error));
3026 ICALL_EXPORT MonoBoolean
3027 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
3029 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
3033 ICALL_EXPORT MonoBoolean
3034 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
3036 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
3041 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
3043 MonoDomain *domain = mono_domain_get ();
3044 MonoImage *image = method->method->klass->image;
3045 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
3046 MonoTableInfo *tables = image->tables;
3047 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
3048 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
3049 guint32 im_cols [MONO_IMPLMAP_SIZE];
3050 guint32 scope_token;
3051 const char *import = NULL;
3052 const char *scope = NULL;
3054 if (image_is_dynamic (image)) {
3055 MonoReflectionMethodAux *method_aux =
3056 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
3058 import = method_aux->dllentry;
3059 scope = method_aux->dll;
3062 if (!import || !scope) {
3063 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
3068 if (piinfo->implmap_idx) {
3069 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
3071 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
3072 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
3073 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
3074 scope = mono_metadata_string_heap (image, scope_token);
3078 *flags = piinfo->piflags;
3079 *entry_point = mono_string_new (domain, import);
3080 *dll_name = mono_string_new (domain, scope);
3083 ICALL_EXPORT MonoReflectionMethod *
3084 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3086 MonoMethodInflated *imethod;
3088 MonoReflectionMethod *ret = NULL;
3091 if (method->method->is_generic)
3094 if (!method->method->is_inflated)
3097 imethod = (MonoMethodInflated *) method->method;
3099 result = imethod->declaring;
3100 /* Not a generic method. */
3101 if (!result->is_generic)
3104 if (image_is_dynamic (method->method->klass->image)) {
3105 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3106 MonoReflectionMethod *res;
3109 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3110 * the dynamic case as well ?
3112 mono_image_lock ((MonoImage*)image);
3113 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3114 mono_image_unlock ((MonoImage*)image);
3120 if (imethod->context.class_inst) {
3121 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3122 /*Generic methods gets the context of the GTD.*/
3123 if (mono_class_get_context (klass)) {
3124 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3125 if (!mono_error_ok (&error))
3130 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3132 if (!mono_error_ok (&error))
3133 mono_error_set_pending_exception (&error);
3137 ICALL_EXPORT gboolean
3138 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3140 return mono_method_signature (method->method)->generic_param_count != 0;
3143 ICALL_EXPORT gboolean
3144 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3146 return method->method->is_generic;
3149 ICALL_EXPORT MonoArray*
3150 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3153 MonoReflectionType *rt;
3158 domain = mono_object_domain (method);
3160 if (method->method->is_inflated) {
3161 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3164 count = inst->type_argc;
3165 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3166 if (mono_error_set_pending_exception (&error))
3169 for (i = 0; i < count; i++) {
3170 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3171 if (mono_error_set_pending_exception (&error))
3174 mono_array_setref (res, i, rt);
3181 count = mono_method_signature (method->method)->generic_param_count;
3182 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3183 if (mono_error_set_pending_exception (&error))
3186 for (i = 0; i < count; i++) {
3187 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3188 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3189 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3191 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3192 if (mono_error_set_pending_exception (&error))
3195 mono_array_setref (res, i, rt);
3201 ICALL_EXPORT MonoObject *
3202 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3206 * Invoke from reflection is supposed to always be a virtual call (the API
3207 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3208 * greater flexibility.
3210 MonoMethod *m = method->method;
3211 MonoMethodSignature *sig = mono_method_signature (m);
3214 void *obj = this_arg;
3218 if (mono_security_core_clr_enabled () &&
3219 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3220 mono_error_set_pending_exception (&error);
3224 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3225 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3226 mono_error_cleanup (&error); /* FIXME does this make sense? */
3227 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3232 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3233 if (!is_ok (&error)) {
3234 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3237 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3238 char *target_name = mono_type_get_full_name (m->klass);
3239 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3240 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3242 g_free (target_name);
3246 m = mono_object_get_virtual_method (this_arg, m);
3247 /* must pass the pointer to the value for valuetype methods */
3248 if (m->klass->valuetype)
3249 obj = mono_object_unbox (this_arg);
3250 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3251 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3256 if (sig->ret->byref) {
3257 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"));
3261 pcount = params? mono_array_length (params): 0;
3262 if (pcount != sig->param_count) {
3263 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3267 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this_arg) {
3268 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."));
3272 image = m->klass->image;
3273 if (image->assembly->ref_only) {
3274 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."));
3278 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3279 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3283 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3287 intptr_t *lower_bounds;
3288 pcount = mono_array_length (params);
3289 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3290 /* Note: the synthetized array .ctors have int32 as argument type */
3291 for (i = 0; i < pcount; ++i)
3292 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3294 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3295 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3296 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3297 if (!mono_error_ok (&error)) {
3298 mono_error_set_pending_exception (&error);
3302 for (i = 0; i < mono_array_length (arr); ++i) {
3303 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3304 if (!mono_error_ok (&error)) {
3305 mono_error_set_pending_exception (&error);
3308 mono_array_setref_fast (arr, i, subarray);
3310 return (MonoObject*)arr;
3313 if (m->klass->rank == pcount) {
3314 /* Only lengths provided. */
3315 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3316 if (!mono_error_ok (&error)) {
3317 mono_error_set_pending_exception (&error);
3321 return (MonoObject*)arr;
3323 g_assert (pcount == (m->klass->rank * 2));
3324 /* The arguments are lower-bound-length pairs */
3325 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3327 for (i = 0; i < pcount / 2; ++i) {
3328 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3329 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3332 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3333 if (!mono_error_ok (&error)) {
3334 mono_error_set_pending_exception (&error);
3338 return (MonoObject*)arr;
3341 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3342 mono_error_set_pending_exception (&error);
3346 #ifndef DISABLE_REMOTING
3347 ICALL_EXPORT MonoObject *
3348 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3351 MonoDomain *domain = mono_object_domain (method);
3352 MonoMethod *m = method->method;
3353 MonoMethodSignature *sig = mono_method_signature (m);
3354 MonoArray *out_args;
3356 int i, j, outarg_count = 0;
3358 if (m->klass == mono_defaults.object_class) {
3359 if (!strcmp (m->name, "FieldGetter")) {
3360 MonoClass *k = this_arg->vtable->klass;
3364 /* If this is a proxy, then it must be a CBO */
3365 if (k == mono_defaults.transparent_proxy_class) {
3366 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3367 this_arg = tp->rp->unwrapped_server;
3368 g_assert (this_arg);
3369 k = this_arg->vtable->klass;
3372 name = mono_array_get (params, MonoString *, 1);
3373 str = mono_string_to_utf8_checked (name, &error);
3374 if (mono_error_set_pending_exception (&error))
3378 MonoClassField* field = mono_class_get_field_from_name (k, str);
3381 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3382 if (field_klass->valuetype) {
3383 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3384 if (mono_error_set_pending_exception (&error))
3387 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3389 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3390 if (mono_error_set_pending_exception (&error))
3392 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3393 mono_array_setref (out_args, 0, result);
3400 g_assert_not_reached ();
3402 } else if (!strcmp (m->name, "FieldSetter")) {
3403 MonoClass *k = this_arg->vtable->klass;
3409 /* If this is a proxy, then it must be a CBO */
3410 if (k == mono_defaults.transparent_proxy_class) {
3411 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3412 this_arg = tp->rp->unwrapped_server;
3413 g_assert (this_arg);
3414 k = this_arg->vtable->klass;
3417 name = mono_array_get (params, MonoString *, 1);
3418 str = mono_string_to_utf8_checked (name, &error);
3419 if (mono_error_set_pending_exception (&error))
3423 MonoClassField* field = mono_class_get_field_from_name (k, str);
3426 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3427 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3429 if (field_klass->valuetype) {
3430 size = mono_type_size (field->type, &align);
3431 g_assert (size == mono_class_value_size (field_klass, NULL));
3432 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3434 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3437 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3438 if (mono_error_set_pending_exception (&error))
3440 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3449 g_assert_not_reached ();
3454 for (i = 0; i < mono_array_length (params); i++) {
3455 if (sig->params [i]->byref)
3459 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3460 if (mono_error_set_pending_exception (&error))
3463 /* handle constructors only for objects already allocated */
3464 if (!strcmp (method->method->name, ".ctor"))
3465 g_assert (this_arg);
3467 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3468 g_assert (!method->method->klass->valuetype);
3469 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3470 if (mono_error_set_pending_exception (&error))
3473 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3474 if (sig->params [i]->byref) {
3476 arg = mono_array_get (params, gpointer, i);
3477 mono_array_setref (out_args, j, arg);
3482 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3489 read_enum_value (const char *mem, int type)
3492 case MONO_TYPE_BOOLEAN:
3494 return *(guint8*)mem;
3496 return *(gint8*)mem;
3497 case MONO_TYPE_CHAR:
3499 return read16 (mem);
3501 return (gint16) read16 (mem);
3503 return read32 (mem);
3505 return (gint32) read32 (mem);
3508 return read64 (mem);
3510 g_assert_not_reached ();
3516 write_enum_value (char *mem, int type, guint64 value)
3520 case MONO_TYPE_I1: {
3521 guint8 *p = (guint8*)mem;
3527 case MONO_TYPE_CHAR: {
3528 guint16 *p = (guint16 *)mem;
3533 case MONO_TYPE_I4: {
3534 guint32 *p = (guint32 *)mem;
3539 case MONO_TYPE_I8: {
3540 guint64 *p = (guint64 *)mem;
3545 g_assert_not_reached ();
3550 ICALL_EXPORT MonoObject *
3551 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3559 domain = mono_object_domain (enumType);
3560 enumc = mono_class_from_mono_type (enumType->type);
3562 mono_class_init_checked (enumc, &error);
3563 if (mono_error_set_pending_exception (&error))
3566 etype = mono_class_enum_basetype (enumc);
3568 res = mono_object_new_checked (domain, enumc, &error);
3569 if (mono_error_set_pending_exception (&error))
3571 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3576 ICALL_EXPORT MonoBoolean
3577 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3579 int size = mono_class_value_size (a->vtable->klass, NULL);
3580 guint64 a_val = 0, b_val = 0;
3582 memcpy (&a_val, mono_object_unbox (a), size);
3583 memcpy (&b_val, mono_object_unbox (b), size);
3585 return (a_val & b_val) == b_val;
3588 ICALL_EXPORT MonoObject *
3589 ves_icall_System_Enum_get_value (MonoObject *eobj)
3601 g_assert (eobj->vtable->klass->enumtype);
3603 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3604 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3605 if (mono_error_set_pending_exception (&error))
3607 dst = (char *)res + sizeof (MonoObject);
3608 src = (char *)eobj + sizeof (MonoObject);
3609 size = mono_class_value_size (enumc, NULL);
3611 memcpy (dst, src, size);
3616 ICALL_EXPORT MonoReflectionType *
3617 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3620 MonoReflectionType *ret;
3624 klass = mono_class_from_mono_type (type->type);
3625 mono_class_init_checked (klass, &error);
3626 if (mono_error_set_pending_exception (&error))
3629 etype = mono_class_enum_basetype (klass);
3631 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3635 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3636 mono_error_set_pending_exception (&error);
3642 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3644 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3645 gpointer odata = (char *)other + sizeof (MonoObject);
3646 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3647 g_assert (basetype);
3652 if (eobj->vtable->klass != other->vtable->klass)
3655 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3656 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3657 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3660 return me > other ? 1 : -1; \
3663 switch (basetype->type) {
3665 COMPARE_ENUM_VALUES (guint8);
3667 COMPARE_ENUM_VALUES (gint8);
3668 case MONO_TYPE_CHAR:
3670 COMPARE_ENUM_VALUES (guint16);
3672 COMPARE_ENUM_VALUES (gint16);
3674 COMPARE_ENUM_VALUES (guint32);
3676 COMPARE_ENUM_VALUES (gint32);
3678 COMPARE_ENUM_VALUES (guint64);
3680 COMPARE_ENUM_VALUES (gint64);
3684 #undef COMPARE_ENUM_VALUES
3685 /* indicates that the enum was of an unsupported unerlying type */
3690 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3692 gpointer data = (char *)eobj + sizeof (MonoObject);
3693 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3694 g_assert (basetype);
3696 switch (basetype->type) {
3697 case MONO_TYPE_I1: {
3698 gint8 value = *((gint8*)data);
3699 return ((int)value ^ (int)value << 8);
3702 return *((guint8*)data);
3703 case MONO_TYPE_CHAR:
3705 return *((guint16*)data);
3707 case MONO_TYPE_I2: {
3708 gint16 value = *((gint16*)data);
3709 return ((int)(guint16)value | (((int)value) << 16));
3712 return *((guint32*)data);
3714 return *((gint32*)data);
3716 case MONO_TYPE_I8: {
3717 gint64 value = *((gint64*)data);
3718 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3721 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3726 ICALL_EXPORT MonoBoolean
3727 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionType *type, MonoArray **values, MonoArray **names)
3730 MonoDomain *domain = mono_object_domain (type);
3731 MonoClass *enumc = mono_class_from_mono_type (type->type);
3732 guint j = 0, nvalues;
3734 MonoClassField *field;
3736 guint64 field_value, previous_value = 0;
3737 gboolean sorted = TRUE;
3739 mono_class_init_checked (enumc, &error);
3740 if (mono_error_set_pending_exception (&error))
3744 if (!enumc->enumtype) {
3745 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3749 base_type = mono_class_enum_basetype (enumc)->type;
3751 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3752 *names = mono_array_new_checked (domain, mono_defaults.string_class, nvalues, &error);
3753 if (mono_error_set_pending_exception (&error))
3755 *values = mono_array_new_checked (domain, mono_defaults.uint64_class, nvalues, &error);
3756 if (mono_error_set_pending_exception (&error))
3760 while ((field = mono_class_get_fields (enumc, &iter))) {
3762 MonoTypeEnum def_type;
3764 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3766 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3768 if (mono_field_is_deleted (field))
3770 mono_array_setref (*names, j, mono_string_new (domain, mono_field_get_name (field)));
3772 p = mono_class_get_field_default_value (field, &def_type);
3773 /* len = */ mono_metadata_decode_blob_size (p, &p);
3775 field_value = read_enum_value (p, base_type);
3776 mono_array_set (*values, guint64, j, field_value);
3778 if (previous_value > field_value)
3781 previous_value = field_value;
3789 BFLAGS_IgnoreCase = 1,
3790 BFLAGS_DeclaredOnly = 2,
3791 BFLAGS_Instance = 4,
3793 BFLAGS_Public = 0x10,
3794 BFLAGS_NonPublic = 0x20,
3795 BFLAGS_FlattenHierarchy = 0x40,
3796 BFLAGS_InvokeMethod = 0x100,
3797 BFLAGS_CreateInstance = 0x200,
3798 BFLAGS_GetField = 0x400,
3799 BFLAGS_SetField = 0x800,
3800 BFLAGS_GetProperty = 0x1000,
3801 BFLAGS_SetProperty = 0x2000,
3802 BFLAGS_ExactBinding = 0x10000,
3803 BFLAGS_SuppressChangeType = 0x20000,
3804 BFLAGS_OptionalParamBinding = 0x40000
3807 ICALL_EXPORT GPtrArray*
3808 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3811 MonoClass *startklass, *klass;
3814 int (*compare_func) (const char *s1, const char *s2) = NULL;
3815 MonoClassField *field;
3817 if (type->type->byref) {
3818 return g_ptr_array_new ();
3821 mono_error_init (&error);
3823 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3825 klass = startklass = mono_class_from_mono_type (type->type);
3827 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3830 if (mono_class_has_failure (klass)) {
3831 mono_error_set_for_class_failure (&error, klass);
3836 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3837 guint32 flags = mono_field_get_flags (field);
3839 if (mono_field_is_deleted_with_flags (field, flags))
3841 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3842 if (bflags & BFLAGS_Public)
3844 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3845 if (bflags & BFLAGS_NonPublic) {
3852 if (flags & FIELD_ATTRIBUTE_STATIC) {
3853 if (bflags & BFLAGS_Static)
3854 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3857 if (bflags & BFLAGS_Instance)
3864 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3867 g_ptr_array_add (ptr_array, field);
3869 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3875 g_ptr_array_free (ptr_array, TRUE);
3876 mono_error_set_pending_exception (&error);
3881 method_nonpublic (MonoMethod* method, gboolean start_klass)
3883 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3884 case METHOD_ATTRIBUTE_ASSEM:
3885 return (start_klass || mono_defaults.generic_ilist_class);
3886 case METHOD_ATTRIBUTE_PRIVATE:
3888 case METHOD_ATTRIBUTE_PUBLIC:
3896 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3899 MonoClass *startklass;
3903 /*FIXME, use MonoBitSet*/
3904 guint32 method_slots_default [8];
3905 guint32 *method_slots = NULL;
3906 int (*compare_func) (const char *s1, const char *s2) = NULL;
3908 array = g_ptr_array_new ();
3910 mono_error_init (error);
3913 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3915 /* An optimization for calls made from Delegate:CreateDelegate () */
3916 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3917 method = mono_get_delegate_invoke (klass);
3920 g_ptr_array_add (array, method);
3924 mono_class_setup_methods (klass);
3925 mono_class_setup_vtable (klass);
3926 if (mono_class_has_failure (klass))
3929 if (is_generic_parameter (&klass->byval_arg))
3930 nslots = mono_class_get_vtable_size (klass->parent);
3932 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3933 if (nslots >= sizeof (method_slots_default) * 8) {
3934 method_slots = g_new0 (guint32, nslots / 32 + 1);
3936 method_slots = method_slots_default;
3937 memset (method_slots, 0, sizeof (method_slots_default));
3940 mono_class_setup_methods (klass);
3941 mono_class_setup_vtable (klass);
3942 if (mono_class_has_failure (klass))
3946 while ((method = mono_class_get_methods (klass, &iter))) {
3948 if (method->slot != -1) {
3949 g_assert (method->slot < nslots);
3950 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3952 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3953 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3956 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3958 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3959 if (bflags & BFLAGS_Public)
3961 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3967 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3968 if (bflags & BFLAGS_Static)
3969 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3972 if (bflags & BFLAGS_Instance)
3980 if (compare_func (name, method->name))
3985 g_ptr_array_add (array, method);
3987 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3989 if (method_slots != method_slots_default)
3990 g_free (method_slots);
3995 if (method_slots != method_slots_default)
3996 g_free (method_slots);
3997 g_ptr_array_free (array, TRUE);
3999 g_assert (mono_class_has_failure (klass));
4000 mono_error_set_for_class_failure (error, klass);
4004 ICALL_EXPORT GPtrArray*
4005 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
4008 GPtrArray *method_array;
4011 klass = mono_class_from_mono_type (type->type);
4012 if (type->type->byref) {
4013 return g_ptr_array_new ();
4016 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
4017 mono_error_set_pending_exception (&error);
4018 return method_array;
4021 ICALL_EXPORT GPtrArray*
4022 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
4024 MonoClass *startklass, *klass;
4027 gpointer iter = NULL;
4028 GPtrArray *res_array;
4031 if (type->type->byref) {
4032 return g_ptr_array_new ();
4035 klass = startklass = mono_class_from_mono_type (type->type);
4037 mono_class_setup_methods (klass);
4038 if (mono_class_has_failure (klass)) {
4039 mono_error_init (&error);
4040 mono_error_set_for_class_failure (&error, klass);
4041 mono_error_set_pending_exception (&error);
4045 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
4048 while ((method = mono_class_get_methods (klass, &iter))) {
4050 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
4052 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4053 if (bflags & BFLAGS_Public)
4056 if (bflags & BFLAGS_NonPublic)
4062 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4063 if (bflags & BFLAGS_Static)
4064 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4067 if (bflags & BFLAGS_Instance)
4073 g_ptr_array_add (res_array, method);
4080 property_hash (gconstpointer data)
4082 MonoProperty *prop = (MonoProperty*)data;
4084 return g_str_hash (prop->name);
4088 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4090 if (method1->slot != -1 && method1->slot == method2->slot)
4093 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4094 if (method1->is_inflated)
4095 method1 = ((MonoMethodInflated*) method1)->declaring;
4096 if (method2->is_inflated)
4097 method2 = ((MonoMethodInflated*) method2)->declaring;
4100 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4104 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4106 // Properties are hide-by-name-and-signature
4107 if (!g_str_equal (prop1->name, prop2->name))
4110 /* If we see a property in a generic method, we want to
4111 compare the generic signatures, not the inflated signatures
4112 because we might conflate two properties that were
4116 public T this[T t] { getter { return t; } } // method 1
4117 public U this[U u] { getter { return u; } } // method 2
4120 If we see int Foo<int,int>::Item[int] we need to know if
4121 the indexer came from method 1 or from method 2, and we
4122 shouldn't conflate them. (Bugzilla 36283)
4124 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4127 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4134 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4139 return method_nonpublic (accessor, start_klass);
4142 ICALL_EXPORT GPtrArray*
4143 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4146 MonoClass *startklass, *klass;
4151 int (*compare_func) (const char *s1, const char *s2) = NULL;
4153 GHashTable *properties = NULL;
4154 GPtrArray *res_array;
4156 if (type->type->byref) {
4157 return g_ptr_array_new ();
4160 mono_error_init (&error);
4162 klass = startklass = mono_class_from_mono_type (type->type);
4164 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4166 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4168 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4170 mono_class_setup_methods (klass);
4171 mono_class_setup_vtable (klass);
4172 if (mono_class_has_failure (klass)) {
4173 mono_error_set_for_class_failure (&error, klass);
4178 while ((prop = mono_class_get_properties (klass, &iter))) {
4184 flags = method->flags;
4187 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4188 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4189 if (bflags & BFLAGS_Public)
4191 } else if (bflags & BFLAGS_NonPublic) {
4192 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4193 property_accessor_nonpublic(prop->set, startklass == klass)) {
4200 if (flags & METHOD_ATTRIBUTE_STATIC) {
4201 if (bflags & BFLAGS_Static)
4202 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4205 if (bflags & BFLAGS_Instance)
4213 if (propname != NULL && compare_func (propname, prop->name))
4216 if (g_hash_table_lookup (properties, prop))
4219 g_ptr_array_add (res_array, prop);
4221 g_hash_table_insert (properties, prop, prop);
4223 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4226 g_hash_table_destroy (properties);
4233 g_hash_table_destroy (properties);
4234 g_ptr_array_free (res_array, TRUE);
4236 mono_error_set_pending_exception (&error);
4242 event_hash (gconstpointer data)
4244 MonoEvent *event = (MonoEvent*)data;
4246 return g_str_hash (event->name);
4250 event_equal (MonoEvent *event1, MonoEvent *event2)
4252 // Events are hide-by-name
4253 return g_str_equal (event1->name, event2->name);
4256 ICALL_EXPORT GPtrArray*
4257 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4260 MonoClass *startklass, *klass;
4265 int (*compare_func) (const char *s1, const char *s2) = NULL;
4266 GHashTable *events = NULL;
4267 GPtrArray *res_array;
4269 if (type->type->byref) {
4270 return g_ptr_array_new ();
4273 mono_error_init (&error);
4275 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4277 res_array = g_ptr_array_sized_new (4);
4279 klass = startklass = mono_class_from_mono_type (type->type);
4281 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4283 mono_class_setup_methods (klass);
4284 mono_class_setup_vtable (klass);
4285 if (mono_class_has_failure (klass)) {
4286 mono_error_set_for_class_failure (&error, klass);
4291 while ((event = mono_class_get_events (klass, &iter))) {
4293 method = event->add;
4295 method = event->remove;
4297 method = event->raise;
4299 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4300 if (bflags & BFLAGS_Public)
4302 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4303 if (bflags & BFLAGS_NonPublic)
4308 if (bflags & BFLAGS_NonPublic)
4314 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4315 if (bflags & BFLAGS_Static)
4316 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4319 if (bflags & BFLAGS_Instance)
4324 if (bflags & BFLAGS_Instance)
4329 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4332 if (g_hash_table_lookup (events, event))
4335 g_ptr_array_add (res_array, event);
4337 g_hash_table_insert (events, event, event);
4339 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4342 g_hash_table_destroy (events);
4348 g_hash_table_destroy (events);
4350 g_ptr_array_free (res_array, TRUE);
4352 mono_error_set_pending_exception (&error);
4356 ICALL_EXPORT GPtrArray *
4357 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4363 GPtrArray *res_array;
4365 if (type->type->byref) {
4366 return g_ptr_array_new ();
4369 klass = mono_class_from_mono_type (type->type);
4372 * If a nested type is generic, return its generic type definition.
4373 * Note that this means that the return value is essentially the set
4374 * of nested types of the generic type definition of @klass.
4376 * A note in MSDN claims that a generic type definition can have
4377 * nested types that aren't generic. In any case, the container of that
4378 * nested type would be the generic type definition.
4380 if (klass->generic_class)
4381 klass = klass->generic_class->container_class;
4383 res_array = g_ptr_array_new ();
4386 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4388 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4389 if (bflags & BFLAGS_Public)
4392 if (bflags & BFLAGS_NonPublic)
4398 if (str != NULL && strcmp (nested->name, str))
4401 g_ptr_array_add (res_array, &nested->byval_arg);
4407 ICALL_EXPORT MonoReflectionType*
4408 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4411 MonoReflectionType *ret;
4413 MonoType *type = NULL;
4414 MonoTypeNameParse info;
4415 gboolean type_resolve;
4417 /* On MS.NET, this does not fire a TypeResolve event */
4418 type_resolve = TRUE;
4419 str = mono_string_to_utf8_checked (name, &error);
4420 if (mono_error_set_pending_exception (&error))
4422 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4423 if (!mono_reflection_parse_type (str, &info)) {
4425 mono_reflection_free_type_info (&info);
4427 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4430 /*g_print ("failed parse\n");*/
4434 if (info.assembly.name) {
4436 mono_reflection_free_type_info (&info);
4438 /* 1.0 and 2.0 throw different exceptions */
4439 if (mono_defaults.generic_ilist_class)
4440 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4442 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4448 if (module != NULL) {
4449 if (module->image) {
4450 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4451 if (!is_ok (&error)) {
4453 mono_reflection_free_type_info (&info);
4454 mono_error_set_pending_exception (&error);
4461 if (assembly_is_dynamic (assembly->assembly)) {
4462 /* Enumerate all modules */
4463 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4467 if (abuilder->modules) {
4468 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4469 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4470 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4471 if (!is_ok (&error)) {
4473 mono_reflection_free_type_info (&info);
4474 mono_error_set_pending_exception (&error);
4482 if (!type && abuilder->loaded_modules) {
4483 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4484 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4485 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4486 if (!is_ok (&error)) {
4488 mono_reflection_free_type_info (&info);
4489 mono_error_set_pending_exception (&error);
4498 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4499 if (!is_ok (&error)) {
4501 mono_reflection_free_type_info (&info);
4502 mono_error_set_pending_exception (&error);
4507 mono_reflection_free_type_info (&info);
4509 MonoException *e = NULL;
4512 e = mono_get_exception_type_load (name, NULL);
4515 mono_set_pending_exception (e);
4519 if (type->type == MONO_TYPE_CLASS) {
4520 MonoClass *klass = mono_type_get_class (type);
4522 /* need to report exceptions ? */
4523 if (throwOnError && mono_class_has_failure (klass)) {
4524 /* report SecurityException (or others) that occured when loading the assembly */
4525 MonoException *exc = mono_class_get_exception_for_failure (klass);
4526 mono_set_pending_exception (exc);
4531 /* g_print ("got it\n"); */
4532 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4533 mono_error_set_pending_exception (&error);
4539 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4542 gchar *shadow_ini_file;
4545 /* Check for shadow-copied assembly */
4546 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4547 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4549 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4550 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4556 g_free (shadow_ini_file);
4557 if (content != NULL) {
4560 *filename = content;
4567 ICALL_EXPORT MonoString *
4568 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4570 MonoDomain *domain = mono_object_domain (assembly);
4571 MonoAssembly *mass = assembly->assembly;
4572 MonoString *res = NULL;
4577 if (g_path_is_absolute (mass->image->name)) {
4578 absolute = g_strdup (mass->image->name);
4579 dirname = g_path_get_dirname (absolute);
4581 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4582 dirname = g_strdup (mass->basedir);
4585 replace_shadow_path (domain, dirname, &absolute);
4590 for (i = strlen (absolute) - 1; i >= 0; i--)
4591 if (absolute [i] == '\\')
4596 uri = g_filename_to_uri (absolute, NULL, NULL);
4598 const char *prepend = "file://";
4600 if (*absolute == '/' && *(absolute + 1) == '/') {
4603 prepend = "file:///";
4606 uri = g_strconcat (prepend, absolute, NULL);
4610 res = mono_string_new (domain, uri);
4617 ICALL_EXPORT MonoBoolean
4618 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4620 MonoAssembly *mass = assembly->assembly;
4622 return mass->in_gac;
4625 ICALL_EXPORT MonoReflectionAssembly*
4626 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4631 MonoImageOpenStatus status;
4632 MonoReflectionAssembly* result = NULL;
4634 name = mono_string_to_utf8_checked (mname, &error);
4635 if (mono_error_set_pending_exception (&error))
4637 res = mono_assembly_load_with_partial_name (name, &status);
4643 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4645 mono_error_set_pending_exception (&error);
4649 ICALL_EXPORT MonoString *
4650 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4652 MonoDomain *domain = mono_object_domain (assembly);
4655 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4660 ICALL_EXPORT MonoBoolean
4661 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4663 return assembly->assembly->ref_only;
4666 ICALL_EXPORT MonoString *
4667 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4669 MonoDomain *domain = mono_object_domain (assembly);
4671 return mono_string_new (domain, assembly->assembly->image->version);
4674 ICALL_EXPORT MonoReflectionMethod*
4675 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4678 MonoReflectionMethod *res = NULL;
4681 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4685 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4686 if (!mono_error_ok (&error))
4689 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4692 if (!mono_error_ok (&error))
4693 mono_error_set_pending_exception (&error);
4697 ICALL_EXPORT MonoReflectionModule*
4698 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4701 MonoReflectionModule *result = NULL;
4702 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4703 if (!mono_error_ok (&error))
4704 mono_error_set_pending_exception (&error);
4708 ICALL_EXPORT MonoArray*
4709 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4712 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4713 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4714 if (mono_error_set_pending_exception (&error))
4719 for (i = 0; i < table->rows; ++i) {
4720 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4721 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4726 ICALL_EXPORT MonoString*
4727 ves_icall_System_Reflection_Assembly_GetAotId ()
4730 guint8 aotid_sum = 0;
4731 MonoDomain* domain = mono_domain_get ();
4733 if (!domain->entry_assembly || !domain->entry_assembly->image)
4736 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4738 for (i = 0; i < 16; ++i)
4739 aotid_sum |= (*aotid)[i];
4744 return mono_string_new (domain, mono_guid_to_string((guint8*) aotid));
4748 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision, MonoError *error)
4750 static MonoMethod *create_version = NULL;
4754 mono_error_init (error);
4757 if (!create_version) {
4758 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4759 create_version = mono_method_desc_search_in_class (desc, mono_class_get_system_version_class ());
4760 g_assert (create_version);
4761 mono_method_desc_free (desc);
4767 args [3] = &revision;
4768 result = mono_object_new_checked (domain, mono_class_get_system_version_class (), error);
4769 return_val_if_nok (error, NULL);
4771 mono_runtime_invoke_checked (create_version, result, args, error);
4772 return_val_if_nok (error, NULL);
4777 ICALL_EXPORT MonoArray*
4778 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4782 MonoDomain *domain = mono_object_domain (assembly);
4784 static MonoMethod *create_culture = NULL;
4785 MonoImage *image = assembly->assembly->image;
4789 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4792 result = mono_array_new_checked (domain, mono_class_get_assembly_name_class (), count, &error);
4793 if (mono_error_set_pending_exception (&error))
4797 if (count > 0 && !create_culture) {
4798 MonoMethodDesc *desc = mono_method_desc_new (
4799 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4800 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4801 g_assert (create_culture);
4802 mono_method_desc_free (desc);
4805 for (i = 0; i < count; i++) {
4806 MonoObject *version;
4807 MonoReflectionAssemblyName *aname;
4808 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4810 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4812 aname = (MonoReflectionAssemblyName *) mono_object_new_checked (
4813 domain, mono_class_get_assembly_name_class (), &error);
4814 if (mono_error_set_pending_exception (&error))
4817 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4819 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4820 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4821 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4822 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4823 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4824 aname->versioncompat = 1; /* SameMachine (default) */
4825 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4827 version = create_version (domain, aname->major, aname->minor, aname->build, aname->revision, &error);
4828 if (mono_error_set_pending_exception (&error))
4831 MONO_OBJECT_SETREF (aname, version, version);
4833 if (create_culture) {
4835 MonoBoolean assembly_ref = 1;
4836 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4837 args [1] = &assembly_ref;
4839 o = mono_runtime_invoke_checked (create_culture, NULL, args, &error);
4840 if (mono_error_set_pending_exception (&error))
4843 MONO_OBJECT_SETREF (aname, cultureInfo, o);
4846 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4847 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4848 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4850 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4851 /* public key token isn't copied - the class library will
4852 automatically generate it from the public key if required */
4853 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4854 if (mono_error_set_pending_exception (&error))
4857 MONO_OBJECT_SETREF (aname, publicKey, pkey);
4858 memcpy (mono_array_addr (pkey, guint8, 0), pkey_ptr, pkey_len);
4860 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, &error);
4861 if (mono_error_set_pending_exception (&error))
4864 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4865 memcpy (mono_array_addr (keyToken, guint8, 0), pkey_ptr, pkey_len);
4868 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, &error);
4869 if (mono_error_set_pending_exception (&error))
4872 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
4875 /* note: this function doesn't return the codebase on purpose (i.e. it can
4876 be used under partial trust as path information isn't present). */
4878 mono_array_setref (result, i, aname);
4883 /* move this in some file in mono/util/ */
4885 g_concat_dir_and_file (const char *dir, const char *file)
4887 g_return_val_if_fail (dir != NULL, NULL);
4888 g_return_val_if_fail (file != NULL, NULL);
4891 * If the directory name doesn't have a / on the end, we need
4892 * to add one so we get a proper path to the file
4894 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4895 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4897 return g_strconcat (dir, file, NULL);
4901 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4904 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4906 guint32 cols [MONO_MANIFEST_SIZE];
4907 guint32 impl, file_idx;
4911 char *n = mono_string_to_utf8_checked (name, &error);
4912 if (mono_error_set_pending_exception (&error))
4915 for (i = 0; i < table->rows; ++i) {
4916 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4917 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4918 if (strcmp (val, n) == 0)
4922 if (i == table->rows)
4925 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4928 * this code should only be called after obtaining the
4929 * ResourceInfo and handling the other cases.
4931 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4932 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4934 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4939 module = assembly->assembly->image;
4942 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4943 if (mono_error_set_pending_exception (&error))
4945 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4947 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4950 ICALL_EXPORT gboolean
4951 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4954 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4956 guint32 cols [MONO_MANIFEST_SIZE];
4957 guint32 file_cols [MONO_FILE_SIZE];
4961 n = mono_string_to_utf8_checked (name, &error);
4962 if (mono_error_set_pending_exception (&error))
4964 for (i = 0; i < table->rows; ++i) {
4965 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4966 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4967 if (strcmp (val, n) == 0)
4971 if (i == table->rows)
4974 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4975 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4978 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4979 case MONO_IMPLEMENTATION_FILE:
4980 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4981 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4982 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4983 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4984 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4985 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4988 info->location = RESOURCE_LOCATION_EMBEDDED;
4991 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4992 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4993 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4994 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4995 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4996 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4998 mono_set_pending_exception (ex);
5001 MonoReflectionAssembly *assm_obj;
5002 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
5004 mono_error_set_pending_exception (&error);
5007 MONO_OBJECT_SETREF (info, assembly, assm_obj);
5009 /* Obtain info recursively */
5010 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
5011 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
5014 case MONO_IMPLEMENTATION_EXP_TYPE:
5015 g_assert_not_reached ();
5023 ICALL_EXPORT MonoObject*
5024 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
5027 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
5028 MonoArray *result = NULL;
5033 /* check hash if needed */
5035 n = mono_string_to_utf8_checked (name, &error);
5036 if (mono_error_set_pending_exception (&error))
5039 for (i = 0; i < table->rows; ++i) {
5040 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
5041 if (strcmp (val, n) == 0) {
5044 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
5045 fn = mono_string_new (mono_object_domain (assembly), n);
5047 return (MonoObject*)fn;
5055 for (i = 0; i < table->rows; ++i) {
5056 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
5060 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
5061 if (mono_error_set_pending_exception (&error))
5066 for (i = 0; i < table->rows; ++i) {
5067 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5068 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
5069 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
5070 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
5075 return (MonoObject*)result;
5078 ICALL_EXPORT MonoArray*
5079 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
5082 MonoDomain *domain = mono_domain_get();
5085 int i, j, file_count = 0;
5086 MonoImage **modules;
5087 guint32 module_count, real_module_count;
5088 MonoTableInfo *table;
5089 guint32 cols [MONO_FILE_SIZE];
5090 MonoImage *image = assembly->assembly->image;
5092 g_assert (image != NULL);
5093 g_assert (!assembly_is_dynamic (assembly->assembly));
5095 table = &image->tables [MONO_TABLE_FILE];
5096 file_count = table->rows;
5098 modules = image->modules;
5099 module_count = image->module_count;
5101 real_module_count = 0;
5102 for (i = 0; i < module_count; ++i)
5104 real_module_count ++;
5106 klass = mono_class_get_module_class ();
5107 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
5108 if (mono_error_set_pending_exception (&error))
5111 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
5112 if (mono_error_set_pending_exception (&error))
5115 mono_array_setref (res, 0, image_obj);
5117 for (i = 0; i < module_count; ++i)
5119 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
5120 if (mono_error_set_pending_exception (&error))
5122 mono_array_setref (res, j, rm);
5126 for (i = 0; i < file_count; ++i, ++j) {
5127 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
5128 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
5129 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
5130 if (mono_error_set_pending_exception (&error))
5132 mono_array_setref (res, j, rm);
5135 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
5137 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
5138 mono_set_pending_exception (mono_get_exception_file_not_found2 (NULL, fname));
5141 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
5142 if (mono_error_set_pending_exception (&error))
5144 mono_array_setref (res, j, rm);
5151 ICALL_EXPORT MonoReflectionMethod*
5152 ves_icall_GetCurrentMethod (void)
5154 MonoReflectionMethod *res = NULL;
5157 MonoMethod *m = mono_method_get_last_managed ();
5160 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5164 while (m->is_inflated)
5165 m = ((MonoMethodInflated*)m)->declaring;
5167 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5168 mono_error_set_pending_exception (&error);
5174 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5177 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5180 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5181 //method is inflated, we should inflate it on the other class
5182 MonoGenericContext ctx;
5183 ctx.method_inst = inflated->context.method_inst;
5184 ctx.class_inst = inflated->context.class_inst;
5185 if (klass->generic_class)
5186 ctx.class_inst = klass->generic_class->context.class_inst;
5187 else if (klass->generic_container)
5188 ctx.class_inst = klass->generic_container->context.class_inst;
5189 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5190 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5194 mono_class_setup_methods (method->klass);
5195 if (mono_class_has_failure (method->klass))
5197 for (i = 0; i < method->klass->method.count; ++i) {
5198 if (method->klass->methods [i] == method) {
5203 mono_class_setup_methods (klass);
5204 if (mono_class_has_failure (klass))
5206 g_assert (offset >= 0 && offset < klass->method.count);
5207 return klass->methods [offset];
5210 ICALL_EXPORT MonoReflectionMethod*
5211 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5213 MonoReflectionMethod *res = NULL;
5216 if (type && generic_check) {
5217 klass = mono_class_from_mono_type (type);
5218 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5221 if (method->klass != klass) {
5222 method = mono_method_get_equivalent_method (method, klass);
5227 klass = mono_class_from_mono_type (type);
5229 klass = method->klass;
5230 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5231 mono_error_set_pending_exception (&error);
5235 ICALL_EXPORT MonoReflectionMethodBody*
5236 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5239 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5240 mono_error_set_pending_exception (&error);
5244 ICALL_EXPORT MonoReflectionAssembly*
5245 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5248 MonoReflectionAssembly *result;
5249 MonoMethod *dest = NULL;
5251 mono_stack_walk_no_il (get_executing, &dest);
5253 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5255 mono_error_set_pending_exception (&error);
5260 ICALL_EXPORT MonoReflectionAssembly*
5261 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5264 MonoReflectionAssembly *result;
5265 MonoDomain* domain = mono_domain_get ();
5267 if (!domain->entry_assembly)
5270 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5272 mono_error_set_pending_exception (&error);
5276 ICALL_EXPORT MonoReflectionAssembly*
5277 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5282 MonoReflectionAssembly *result;
5285 mono_stack_walk_no_il (get_executing, &dest);
5287 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5291 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5294 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5296 mono_error_set_pending_exception (&error);
5300 ICALL_EXPORT MonoString *
5301 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
5302 gboolean assembly_qualified)
5304 MonoDomain *domain = mono_object_domain (object);
5305 MonoTypeNameFormat format;
5310 format = assembly_qualified ?
5311 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5312 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5314 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5316 name = mono_type_get_name_full (object->type, format);
5320 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
5325 res = mono_string_new (domain, name);
5332 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5335 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5337 mono_class_init_checked (klass, &error);
5338 mono_error_set_pending_exception (&error);
5339 return mono_security_core_clr_class_level (klass);
5343 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5345 MonoClassField *field = rfield->field;
5346 return mono_security_core_clr_field_level (field, TRUE);
5350 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5352 MonoMethod *method = rfield->method;
5353 return mono_security_core_clr_method_level (method, TRUE);
5357 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token, MonoError *error)
5359 static MonoMethod *create_culture = NULL;
5363 const char *pkey_ptr;
5365 MonoBoolean assembly_ref = 0;
5367 mono_error_init (error);
5369 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
5370 aname->major = name->major;
5371 aname->minor = name->minor;
5372 aname->build = name->build;
5373 aname->flags = name->flags;
5374 aname->revision = name->revision;
5375 aname->hashalg = name->hash_alg;
5376 aname->versioncompat = 1; /* SameMachine (default) */
5377 aname->processor_architecture = name->arch;
5379 if (by_default_version) {
5380 MonoObject *version;
5382 version = create_version (domain, name->major, name->minor, name->build, name->revision, error);
5383 return_if_nok (error);
5385 MONO_OBJECT_SETREF (aname, version, version);
5389 if (absolute != NULL && *absolute != '\0') {
5390 const gchar *prepend = "file://";
5393 codebase = g_strdup (absolute);
5398 for (i = strlen (codebase) - 1; i >= 0; i--)
5399 if (codebase [i] == '\\')
5402 if (*codebase == '/' && *(codebase + 1) == '/') {
5405 prepend = "file:///";
5409 result = g_strconcat (prepend, codebase, NULL);
5415 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
5419 if (!create_culture) {
5420 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
5421 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
5422 g_assert (create_culture);
5423 mono_method_desc_free (desc);
5426 if (name->culture) {
5427 args [0] = mono_string_new (domain, name->culture);
5428 args [1] = &assembly_ref;
5430 obj = mono_runtime_invoke_checked (create_culture, NULL, args, error);
5431 return_if_nok (error);
5433 MONO_OBJECT_SETREF (aname, cultureInfo, obj);
5436 if (name->public_key) {
5437 pkey_ptr = (char*)name->public_key;
5438 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
5440 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, pkey_len, error);
5441 return_if_nok (error);
5442 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5443 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
5444 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5445 } else if (default_publickey) {
5446 MonoArray *pkey = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5447 return_if_nok (error);
5448 MONO_OBJECT_SETREF (aname, publicKey, pkey);
5449 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5452 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5453 if (name->public_key_token [0]) {
5457 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 8, error);
5458 return_if_nok (error);
5460 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5461 p = mono_array_addr (keyToken, char, 0);
5463 for (i = 0, j = 0; i < 8; i++) {
5464 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
5465 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
5468 } else if (default_token) {
5469 MonoArray *keyToken = mono_array_new_checked (domain, mono_defaults.byte_class, 0, error);
5470 return_if_nok (error);
5471 MONO_OBJECT_SETREF (aname, keyToken, keyToken);
5475 ICALL_EXPORT MonoString *
5476 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5478 MonoDomain *domain = mono_object_domain (assembly);
5479 MonoAssembly *mass = assembly->assembly;
5483 name = mono_stringify_assembly_name (&mass->aname);
5484 res = mono_string_new (domain, name);
5491 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
5494 gchar *absolute, *dirname;
5495 MonoAssembly *mass = assembly->assembly;
5497 /* XXX this is duplicated code to compute the codebase URI, unify it */
5498 if (g_path_is_absolute (mass->image->name)) {
5499 absolute = g_strdup (mass->image->name);
5500 dirname = g_path_get_dirname (absolute);
5502 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
5503 dirname = g_strdup (mass->basedir);
5506 replace_shadow_path (mono_object_domain (assembly), dirname, &absolute);
5509 fill_reflection_assembly_name (mono_object_domain (assembly), aname, &mass->aname, absolute, TRUE, TRUE, TRUE, &error);
5510 mono_error_set_pending_exception (&error);
5516 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
5520 MonoImageOpenStatus status = MONO_IMAGE_OK;
5523 MonoAssemblyName name;
5526 filename = mono_string_to_utf8_checked (fname, &error);
5527 if (mono_error_set_pending_exception (&error))
5530 dirname = g_path_get_dirname (filename);
5531 replace_shadow_path (mono_domain_get (), dirname, &filename);
5534 image = mono_image_open (filename, &status);
5540 if (status == MONO_IMAGE_IMAGE_INVALID)
5541 exc = mono_get_exception_bad_image_format2 (NULL, fname);
5543 exc = mono_get_exception_file_not_found2 (NULL, fname);
5544 mono_set_pending_exception (exc);
5548 res = mono_assembly_fill_assembly_name (image, &name);
5550 mono_image_close (image);
5552 mono_set_pending_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5556 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE, FALSE, TRUE, &error);
5557 mono_error_set_pending_exception (&error);
5559 mono_image_close (image);
5563 ICALL_EXPORT MonoBoolean
5564 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5565 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5567 MonoBoolean result = FALSE;
5568 MonoDeclSecurityEntry entry;
5570 /* SecurityAction.RequestMinimum */
5571 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5572 *minimum = entry.blob;
5573 *minLength = entry.size;
5576 /* SecurityAction.RequestOptional */
5577 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5578 *optional = entry.blob;
5579 *optLength = entry.size;
5582 /* SecurityAction.RequestRefuse */
5583 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5584 *refused = entry.blob;
5585 *refLength = entry.size;
5593 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5595 guint32 attrs, visibility;
5597 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5598 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5599 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5602 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5608 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **exceptions, MonoBoolean exportedOnly, MonoError *error)
5610 MonoReflectionType *rt;
5613 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5616 mono_error_init (error);
5618 /* we start the count from 1 because we skip the special type <Module> */
5621 for (i = 1; i < tdef->rows; ++i) {
5622 if (mono_module_type_is_visible (tdef, image, i + 1))
5626 count = tdef->rows - 1;
5628 res = mono_array_new_checked (domain, mono_defaults.runtimetype_class, count, error);
5629 return_val_if_nok (error, NULL);
5630 *exceptions = mono_array_new_checked (domain, mono_defaults.exception_class, count, error);
5631 return_val_if_nok (error, NULL);
5633 for (i = 1; i < tdef->rows; ++i) {
5634 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i + 1)) {
5635 klass = mono_class_get_checked (image, (i + 1) | MONO_TOKEN_TYPE_DEF, error);
5638 rt = mono_type_get_object_checked (domain, &klass->byval_arg, error);
5639 return_val_if_nok (error, NULL);
5641 mono_array_setref (res, count, rt);
5643 MonoException *ex = mono_error_convert_to_exception (error);
5644 mono_array_setref (*exceptions, count, ex);
5653 ICALL_EXPORT MonoArray*
5654 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
5657 MonoArray *res = NULL;
5658 MonoArray *exceptions = NULL;
5659 MonoImage *image = NULL;
5660 MonoTableInfo *table = NULL;
5663 int i, len, ex_count;
5665 domain = mono_object_domain (assembly);
5667 g_assert (!assembly_is_dynamic (assembly->assembly));
5668 image = assembly->assembly->image;
5669 table = &image->tables [MONO_TABLE_FILE];
5670 res = mono_module_get_types (domain, image, &exceptions, exportedOnly, &error);
5671 if (mono_error_set_pending_exception (&error))
5674 /* Append data from all modules in the assembly */
5675 for (i = 0; i < table->rows; ++i) {
5676 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5677 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
5682 res2 = mono_module_get_types (domain, loaded_image, &ex2, exportedOnly, &error);
5683 if (mono_error_set_pending_exception (&error))
5687 /* Append the new types to the end of the array */
5688 if (mono_array_length (res2) > 0) {
5690 MonoArray *res3, *ex3;
5692 len1 = mono_array_length (res);
5693 len2 = mono_array_length (res2);
5695 res3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5696 if (mono_error_set_pending_exception (&error))
5698 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5699 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5702 ex3 = mono_array_new_checked (domain, mono_defaults.runtimetype_class, len1 + len2, &error);
5703 if (mono_error_set_pending_exception (&error))
5705 mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
5706 mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
5713 /* the ReflectionTypeLoadException must have all the types (Types property),
5714 * NULL replacing types which throws an exception. The LoaderException must
5715 * contain all exceptions for NULL items.
5718 len = mono_array_length (res);
5721 for (i = 0; i < len; i++) {
5722 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (res, gpointer, i);
5726 klass = mono_type_get_class (t->type);
5727 if ((klass != NULL) && mono_class_has_failure (klass)) {
5728 /* keep the class in the list */
5729 list = g_list_append (list, klass);
5730 /* and replace Type with NULL */
5731 mono_array_setref (res, i, NULL);
5738 if (list || ex_count) {
5740 MonoException *exc = NULL;
5741 MonoArray *exl = NULL;
5742 int j, length = g_list_length (list) + ex_count;
5744 exl = mono_array_new_checked (domain, mono_defaults.exception_class, length, &error);
5745 if (mono_error_set_pending_exception (&error)) {
5749 /* Types for which mono_class_get_checked () succeeded */
5750 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5751 MonoException *exc = mono_class_get_exception_for_failure ((MonoClass *)tmp->data);
5752 mono_array_setref (exl, i, exc);
5754 /* Types for which it don't */
5755 for (j = 0; j < mono_array_length (exceptions); ++j) {
5756 MonoException *exc = mono_array_get (exceptions, MonoException*, j);
5758 g_assert (i < length);
5759 mono_array_setref (exl, i, exc);
5766 exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
5767 if (!is_ok (&error)) {
5768 mono_error_set_pending_exception (&error);
5771 mono_set_pending_exception (exc);
5778 ICALL_EXPORT gboolean
5779 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5782 MonoAssemblyName aname;
5783 MonoDomain *domain = mono_object_domain (name);
5785 gboolean is_version_defined;
5786 gboolean is_token_defined;
5788 aname.public_key = NULL;
5789 val = mono_string_to_utf8_checked (assname, &error);
5790 if (mono_error_set_pending_exception (&error))
5793 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined)) {
5794 g_free ((guint8*) aname.public_key);
5799 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined, FALSE, is_token_defined, &error);
5800 mono_error_set_pending_exception (&error);
5802 mono_assembly_name_free (&aname);
5803 g_free ((guint8*) aname.public_key);
5809 ICALL_EXPORT MonoReflectionType*
5810 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5813 MonoReflectionType *ret;
5814 MonoDomain *domain = mono_object_domain (module);
5817 g_assert (module->image);
5819 if (image_is_dynamic (module->image) && ((MonoDynamicImage*)(module->image))->initial_image)
5820 /* These images do not have a global type */
5823 klass = mono_class_get_checked (module->image, 1 | MONO_TOKEN_TYPE_DEF, &error);
5824 if (!mono_error_ok (&error)) {
5825 mono_error_set_pending_exception (&error);
5829 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
5830 if (!mono_error_ok (&error)) {
5831 mono_error_set_pending_exception (&error);
5839 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5841 /*if (module->image)
5842 mono_image_close (module->image);*/
5845 ICALL_EXPORT MonoString*
5846 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5848 MonoDomain *domain = mono_object_domain (module);
5850 g_assert (module->image);
5851 return mono_string_new (domain, module->image->guid);
5854 ICALL_EXPORT gpointer
5855 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
5858 if (module->image && module->image->is_module_handle)
5859 return module->image->raw_data;
5862 return (gpointer) (-1);
5866 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5868 if (image_is_dynamic (image)) {
5869 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5870 *pe_kind = dyn->pe_kind;
5871 *machine = dyn->machine;
5874 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5875 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5880 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5882 return (image->md_version_major << 16) | (image->md_version_minor);
5885 ICALL_EXPORT MonoArray*
5886 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5889 MonoArray *exceptions;
5892 if (!module->image) {
5893 MonoArray *arr = mono_array_new_checked (mono_object_domain (module), mono_defaults.runtimetype_class, 0, &error);
5894 mono_error_set_pending_exception (&error);
5899 res = mono_module_get_types (mono_object_domain (module), module->image, &exceptions, FALSE, &error);
5900 if (mono_error_set_pending_exception (&error))
5903 for (i = 0; i < mono_array_length (exceptions); ++i) {
5904 MonoException *ex = mono_array_get (exceptions, MonoException *, i);
5906 mono_set_pending_exception (ex);
5915 mono_memberref_is_method (MonoImage *image, guint32 token)
5917 if (!image_is_dynamic (image)) {
5918 guint32 cols [MONO_MEMBERREF_SIZE];
5920 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5921 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5922 mono_metadata_decode_blob_size (sig, &sig);
5923 return (*sig != 0x6);
5926 MonoClass *handle_class;
5928 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5929 mono_error_cleanup (&error); /* just probing, ignore error */
5933 return mono_defaults.methodhandle_class == handle_class;
5938 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5941 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5942 mono_array_addr (type_args, MonoType*, 0));
5944 context->class_inst = NULL;
5946 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5947 mono_array_addr (method_args, MonoType*, 0));
5949 context->method_inst = NULL;
5952 ICALL_EXPORT MonoType*
5953 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5956 int table = mono_metadata_token_table (token);
5957 int index = mono_metadata_token_index (token);
5958 MonoGenericContext context;
5961 *resolve_error = ResolveTokenError_Other;
5963 /* Validate token */
5964 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5965 (table != MONO_TABLE_TYPESPEC)) {
5966 *resolve_error = ResolveTokenError_BadTable;
5970 if (image_is_dynamic (image)) {
5971 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5972 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5973 mono_error_cleanup (&error);
5974 return klass ? &klass->byval_arg : NULL;
5977 init_generic_context_from_args (&context, type_args, method_args);
5978 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5979 mono_error_cleanup (&error);
5980 return klass ? &klass->byval_arg : NULL;
5983 if ((index <= 0) || (index > image->tables [table].rows)) {
5984 *resolve_error = ResolveTokenError_OutOfRange;
5988 init_generic_context_from_args (&context, type_args, method_args);
5989 klass = mono_class_get_checked (image, token, &error);
5991 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5992 if (!mono_error_ok (&error)) {
5993 mono_error_set_pending_exception (&error);
5998 return &klass->byval_arg;
6003 ICALL_EXPORT MonoMethod*
6004 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
6007 int table = mono_metadata_token_table (token);
6008 int index = mono_metadata_token_index (token);
6009 MonoGenericContext context;
6012 *resolve_error = ResolveTokenError_Other;
6014 /* Validate token */
6015 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
6016 (table != MONO_TABLE_MEMBERREF)) {
6017 *resolve_error = ResolveTokenError_BadTable;
6021 if (image_is_dynamic (image)) {
6022 if (table == MONO_TABLE_METHOD) {
6023 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
6024 mono_error_cleanup (&error);
6028 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
6029 *resolve_error = ResolveTokenError_BadTable;
6033 init_generic_context_from_args (&context, type_args, method_args);
6034 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
6035 mono_error_cleanup (&error);
6039 if ((index <= 0) || (index > image->tables [table].rows)) {
6040 *resolve_error = ResolveTokenError_OutOfRange;
6043 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
6044 *resolve_error = ResolveTokenError_BadTable;
6048 init_generic_context_from_args (&context, type_args, method_args);
6049 method = mono_get_method_checked (image, token, NULL, &context, &error);
6050 mono_error_set_pending_exception (&error);
6055 ICALL_EXPORT MonoString*
6056 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6059 int index = mono_metadata_token_index (token);
6061 *resolve_error = ResolveTokenError_Other;
6063 /* Validate token */
6064 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
6065 *resolve_error = ResolveTokenError_BadTable;
6069 if (image_is_dynamic (image)) {
6070 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
6071 mono_error_cleanup (&error);
6075 if ((index <= 0) || (index >= image->heap_us.size)) {
6076 *resolve_error = ResolveTokenError_OutOfRange;
6080 /* FIXME: What to do if the index points into the middle of a string ? */
6082 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
6083 mono_error_set_pending_exception (&error);
6087 ICALL_EXPORT MonoClassField*
6088 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
6092 int table = mono_metadata_token_table (token);
6093 int index = mono_metadata_token_index (token);
6094 MonoGenericContext context;
6095 MonoClassField *field;
6097 *resolve_error = ResolveTokenError_Other;
6099 /* Validate token */
6100 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
6101 *resolve_error = ResolveTokenError_BadTable;
6105 if (image_is_dynamic (image)) {
6106 if (table == MONO_TABLE_FIELD) {
6107 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
6108 mono_error_cleanup (&error);
6112 if (mono_memberref_is_method (image, token)) {
6113 *resolve_error = ResolveTokenError_BadTable;
6117 init_generic_context_from_args (&context, type_args, method_args);
6118 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
6119 mono_error_cleanup (&error);
6123 if ((index <= 0) || (index > image->tables [table].rows)) {
6124 *resolve_error = ResolveTokenError_OutOfRange;
6127 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
6128 *resolve_error = ResolveTokenError_BadTable;
6132 init_generic_context_from_args (&context, type_args, method_args);
6133 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
6134 mono_error_set_pending_exception (&error);
6140 ICALL_EXPORT MonoObject*
6141 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
6145 int table = mono_metadata_token_table (token);
6147 *error = ResolveTokenError_Other;
6150 case MONO_TABLE_TYPEDEF:
6151 case MONO_TABLE_TYPEREF:
6152 case MONO_TABLE_TYPESPEC: {
6153 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
6155 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
6156 mono_error_set_pending_exception (&merror);
6163 case MONO_TABLE_METHOD:
6164 case MONO_TABLE_METHODSPEC: {
6165 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6167 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6168 mono_error_set_pending_exception (&merror);
6174 case MONO_TABLE_FIELD: {
6175 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6177 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6178 mono_error_set_pending_exception (&merror);
6184 case MONO_TABLE_MEMBERREF:
6185 if (mono_memberref_is_method (image, token)) {
6186 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
6188 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
6189 mono_error_set_pending_exception (&merror);
6196 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
6198 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
6199 mono_error_set_pending_exception (&merror);
6208 *error = ResolveTokenError_BadTable;
6214 ICALL_EXPORT MonoArray*
6215 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6218 int table = mono_metadata_token_table (token);
6219 int idx = mono_metadata_token_index (token);
6220 MonoTableInfo *tables = image->tables;
6225 *resolve_error = ResolveTokenError_OutOfRange;
6227 /* FIXME: Support other tables ? */
6228 if (table != MONO_TABLE_STANDALONESIG)
6231 if (image_is_dynamic (image))
6234 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6237 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6239 ptr = mono_metadata_blob_heap (image, sig);
6240 len = mono_metadata_decode_blob_size (ptr, &ptr);
6242 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6243 if (mono_error_set_pending_exception (&error))
6245 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6249 ICALL_EXPORT MonoReflectionType*
6250 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
6253 MonoReflectionType *ret;
6255 int isbyref = 0, rank;
6257 char *str = mono_string_to_utf8_checked (smodifiers, &error);
6258 if (mono_error_set_pending_exception (&error))
6261 klass = mono_class_from_mono_type (tb->type.type);
6263 /* logic taken from mono_reflection_parse_type(): keep in sync */
6267 if (isbyref) { /* only one level allowed by the spec */
6276 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
6277 mono_error_set_pending_exception (&error);
6281 klass = mono_ptr_class_get (&klass->byval_arg);
6282 mono_class_init (klass);
6293 else if (*p != '*') { /* '*' means unknown lower bound */
6304 klass = mono_array_class_get (klass, rank);
6305 mono_class_init (klass);
6314 ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
6315 mono_error_set_pending_exception (&error);
6320 ICALL_EXPORT MonoBoolean
6321 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6327 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6333 check_for_invalid_type (MonoClass *klass, MonoError *error)
6338 mono_error_init (error);
6340 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6343 name = mono_type_get_full_name (klass);
6344 str = mono_string_new (mono_domain_get (), name);
6346 mono_error_set_exception_instance (error, mono_get_exception_type_load (str, NULL));
6349 ICALL_EXPORT MonoReflectionType *
6350 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6353 MonoReflectionType *ret;
6354 MonoClass *klass, *aklass;
6356 klass = mono_class_from_mono_type (type->type);
6357 check_for_invalid_type (klass, &error);
6358 mono_error_set_pending_exception (&error);
6360 if (rank == 0) //single dimentional array
6361 aklass = mono_array_class_get (klass, 1);
6363 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6365 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6366 mono_error_set_pending_exception (&error);
6371 ICALL_EXPORT MonoReflectionType *
6372 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6375 MonoReflectionType *ret;
6378 klass = mono_class_from_mono_type (type->type);
6379 mono_class_init_checked (klass, &error);
6380 if (mono_error_set_pending_exception (&error))
6383 check_for_invalid_type (klass, &error);
6384 if (mono_error_set_pending_exception (&error))
6387 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6388 mono_error_set_pending_exception (&error);
6393 ICALL_EXPORT MonoReflectionType *
6394 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6397 MonoReflectionType *ret;
6398 MonoClass *klass, *pklass;
6400 klass = mono_class_from_mono_type (type->type);
6401 mono_class_init_checked (klass, &error);
6402 if (mono_error_set_pending_exception (&error))
6404 check_for_invalid_type (klass, &error);
6405 if (mono_error_set_pending_exception (&error))
6408 pklass = mono_ptr_class_get (type->type);
6410 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6411 mono_error_set_pending_exception (&error);
6416 ICALL_EXPORT MonoObject *
6417 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6418 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6421 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6422 MonoObject *delegate;
6424 MonoMethod *method = info->method;
6426 mono_class_init_checked (delegate_class, &error);
6427 if (mono_error_set_pending_exception (&error))
6430 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6431 /* FIXME improve this exception message */
6432 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6434 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6435 mono_error_set_pending_exception (&error);
6439 if (mono_security_core_clr_enabled ()) {
6440 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6441 if (throwOnBindFailure)
6442 mono_error_set_pending_exception (&error);
6444 mono_error_cleanup (&error);
6449 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6450 if (mono_error_set_pending_exception (&error))
6453 if (method_is_dynamic (method)) {
6454 /* Creating a trampoline would leak memory */
6455 func = mono_compile_method_checked (method, &error);
6456 if (mono_error_set_pending_exception (&error))
6459 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6460 method = mono_object_get_virtual_method (target, method);
6461 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6462 if (mono_error_set_pending_exception (&error))
6464 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6467 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6468 if (mono_error_set_pending_exception (&error))
6473 ICALL_EXPORT MonoMulticastDelegate *
6474 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6477 MonoMulticastDelegate *ret;
6479 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6481 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6482 if (mono_error_set_pending_exception (&error))
6485 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6490 ICALL_EXPORT MonoReflectionMethod*
6491 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6493 MonoReflectionMethod *ret = NULL;
6495 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6496 mono_error_set_pending_exception (&error);
6502 static inline gint32
6503 mono_array_get_byte_length (MonoArray *array)
6509 klass = array->obj.vtable->klass;
6511 if (array->bounds == NULL)
6512 length = array->max_length;
6515 for (i = 0; i < klass->rank; ++ i)
6516 length *= array->bounds [i].length;
6519 switch (klass->element_class->byval_arg.type) {
6522 case MONO_TYPE_BOOLEAN:
6526 case MONO_TYPE_CHAR:
6534 return length * sizeof (gpointer);
6545 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6547 return mono_array_get_byte_length (array);
6551 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6553 return mono_array_get (array, gint8, idx);
6557 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6559 mono_array_set (array, gint8, idx, value);
6562 ICALL_EXPORT MonoBoolean
6563 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6565 guint8 *src_buf, *dest_buf;
6568 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6572 g_assert (count >= 0);
6574 /* This is called directly from the class libraries without going through the managed wrapper */
6575 MONO_CHECK_ARG_NULL (src, FALSE);
6576 MONO_CHECK_ARG_NULL (dest, FALSE);
6578 /* watch out for integer overflow */
6579 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6582 src_buf = (guint8 *)src->vector + src_offset;
6583 dest_buf = (guint8 *)dest->vector + dest_offset;
6586 memcpy (dest_buf, src_buf, count);
6588 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6593 #ifndef DISABLE_REMOTING
6594 ICALL_EXPORT MonoObject *
6595 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6598 MonoDomain *domain = mono_object_domain (this_obj);
6600 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6601 MonoTransparentProxy *tp;
6605 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6606 if (mono_error_set_pending_exception (&error))
6609 tp = (MonoTransparentProxy*) res;
6611 MONO_OBJECT_SETREF (tp, rp, rp);
6612 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6613 klass = mono_class_from_mono_type (type);
6615 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6616 mono_class_setup_vtable (klass);
6617 if (mono_class_has_failure (klass)) {
6618 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6622 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6623 if (mono_error_set_pending_exception (&error))
6625 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6626 if (mono_error_set_pending_exception (&error))
6629 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6630 if (mono_error_set_pending_exception (&error))
6635 ICALL_EXPORT MonoReflectionType *
6636 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6639 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6640 mono_error_set_pending_exception (&error);
6646 /* System.Environment */
6649 ves_icall_System_Environment_get_UserName (void)
6651 /* using glib is more portable */
6652 return mono_string_new (mono_domain_get (), g_get_user_name ());
6656 ICALL_EXPORT MonoString *
6657 ves_icall_System_Environment_get_MachineName (void)
6659 #if defined (HOST_WIN32)
6664 len = MAX_COMPUTERNAME_LENGTH + 1;
6665 buf = g_new (gunichar2, len);
6668 if (GetComputerName (buf, (PDWORD) &len)) {
6670 result = mono_string_new_utf16_checked (mono_domain_get (), buf, len, &error);
6671 mono_error_set_pending_exception (&error);
6676 #elif !defined(DISABLE_SOCKETS)
6680 #if defined _SC_HOST_NAME_MAX
6681 n = sysconf (_SC_HOST_NAME_MAX);
6685 buf = g_malloc (n+1);
6687 if (gethostname (buf, n) == 0){
6689 result = mono_string_new (mono_domain_get (), buf);
6696 return mono_string_new (mono_domain_get (), "mono");
6701 ves_icall_System_Environment_get_Platform (void)
6703 #if defined (TARGET_WIN32)
6706 #elif defined(__MACH__)
6709 // Notice that the value is hidden from user code, and only exposed
6710 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6711 // define and making assumptions based on Unix/128/4 values before there
6712 // was a MacOS define. Lots of code would assume that not-Unix meant
6713 // Windows, but in this case, it would be OSX.
6722 ICALL_EXPORT MonoString *
6723 ves_icall_System_Environment_get_NewLine (void)
6725 #if defined (HOST_WIN32)
6726 return mono_string_new (mono_domain_get (), "\r\n");
6728 return mono_string_new (mono_domain_get (), "\n");
6732 ICALL_EXPORT MonoBoolean
6733 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6735 #if SIZEOF_VOID_P == 8
6739 gboolean isWow64Process = FALSE;
6740 if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) {
6741 return (MonoBoolean)isWow64Process;
6743 #elif defined(HAVE_SYS_UTSNAME_H)
6744 struct utsname name;
6746 if (uname (&name) >= 0) {
6747 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6754 ICALL_EXPORT MonoString *
6755 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
6764 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6765 if (mono_error_set_pending_exception (&error))
6767 value = g_getenv (utf8_name);
6774 return mono_string_new (mono_domain_get (), value);
6778 * There is no standard way to get at environ.
6781 #ifndef __MINGW32_VERSION
6782 #if defined(__APPLE__)
6783 #if defined (TARGET_OSX)
6784 /* Apple defines this in crt_externs.h but doesn't provide that header for
6785 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6786 * in fact exist on all implementations (so far)
6788 gchar ***_NSGetEnviron(void);
6789 #define environ (*_NSGetEnviron())
6791 static char *mono_environ[1] = { NULL };
6792 #define environ mono_environ
6793 #endif /* defined (TARGET_OSX) */
6801 ICALL_EXPORT MonoArray *
6802 ves_icall_System_Environment_GetCoomandLineArgs (void)
6805 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6806 mono_error_set_pending_exception (&error);
6810 ICALL_EXPORT MonoArray *
6811 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6823 env_strings = GetEnvironmentStrings();
6826 env_string = env_strings;
6827 while (*env_string != '\0') {
6828 /* weird case that MS seems to skip */
6829 if (*env_string != '=')
6831 while (*env_string != '\0')
6837 domain = mono_domain_get ();
6838 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6839 if (mono_error_set_pending_exception (&error))
6844 env_string = env_strings;
6845 while (*env_string != '\0') {
6846 /* weird case that MS seems to skip */
6847 if (*env_string != '=') {
6848 equal_str = wcschr(env_string, '=');
6849 g_assert(equal_str);
6851 str = mono_string_new_utf16_checked (domain, env_string, equal_str-env_string, &error);
6852 if (mono_error_set_pending_exception (&error))
6855 mono_array_setref (names, n, str);
6858 while (*env_string != '\0')
6863 FreeEnvironmentStrings (env_strings);
6877 for (e = environ; *e != 0; ++ e)
6880 domain = mono_domain_get ();
6881 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6882 if (mono_error_set_pending_exception (&error))
6886 for (e = environ; *e != 0; ++ e) {
6887 parts = g_strsplit (*e, "=", 2);
6889 str = mono_string_new (domain, *parts);
6890 mono_array_setref (names, n, str);
6903 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6906 gunichar2 *utf16_name, *utf16_value;
6908 gchar *utf8_name, *utf8_value;
6913 utf16_name = mono_string_to_utf16 (name);
6914 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6915 SetEnvironmentVariable (utf16_name, NULL);
6916 g_free (utf16_name);
6920 utf16_value = mono_string_to_utf16 (value);
6922 SetEnvironmentVariable (utf16_name, utf16_value);
6924 g_free (utf16_name);
6925 g_free (utf16_value);
6927 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6928 if (mono_error_set_pending_exception (&error))
6931 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6932 g_unsetenv (utf8_name);
6937 utf8_value = mono_string_to_utf8_checked (value, &error);
6938 if (!mono_error_ok (&error)) {
6940 mono_error_set_pending_exception (&error);
6943 g_setenv (utf8_name, utf8_value, TRUE);
6946 g_free (utf8_value);
6951 ves_icall_System_Environment_Exit (int result)
6953 mono_environment_exitcode_set (result);
6955 /* FIXME: There are some cleanup hangs that should be worked out, but
6956 * if the program is going to exit, everything will be cleaned up when
6957 * NaCl exits anyway.
6959 #ifndef __native_client__
6960 if (!mono_runtime_try_shutdown ())
6961 mono_thread_exit ();
6963 /* Suspend all managed threads since the runtime is going away */
6964 mono_thread_suspend_all_other_threads ();
6966 mono_runtime_quit ();
6969 /* we may need to do some cleanup here... */
6973 ICALL_EXPORT MonoString*
6974 ves_icall_System_Environment_GetGacPath (void)
6976 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6979 ICALL_EXPORT MonoString*
6980 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6982 #if defined (HOST_WIN32)
6983 #ifndef CSIDL_FLAG_CREATE
6984 #define CSIDL_FLAG_CREATE 0x8000
6987 WCHAR path [MAX_PATH];
6988 /* Create directory if no existing */
6989 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6994 MonoString *res = mono_string_new_utf16_checked (mono_domain_get (), path, len, &error);
6995 mono_error_set_pending_exception (&error);
6999 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
7001 return mono_string_new (mono_domain_get (), "");
7004 ICALL_EXPORT MonoArray *
7005 ves_icall_System_Environment_GetLogicalDrives (void)
7008 gunichar2 buf [256], *ptr, *dname;
7010 guint initial_size = 127, size = 128;
7013 MonoString *drivestr;
7014 MonoDomain *domain = mono_domain_get ();
7020 while (size > initial_size) {
7021 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
7022 if (size > initial_size) {
7025 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
7026 initial_size = size;
7040 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
7041 if (mono_error_set_pending_exception (&error))
7048 while (*u16) { u16++; len ++; }
7049 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
7050 if (mono_error_set_pending_exception (&error))
7053 mono_array_setref (result, ndrives++, drivestr);
7064 ICALL_EXPORT MonoString *
7065 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
7068 gunichar2 volume_name [MAX_PATH + 1];
7070 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
7072 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
7073 mono_error_set_pending_exception (&error);
7077 ICALL_EXPORT MonoString *
7078 ves_icall_System_Environment_InternalGetHome (void)
7080 return mono_string_new (mono_domain_get (), g_get_home_dir ());
7083 static const char *encodings [] = {
7085 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
7086 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
7087 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
7089 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
7090 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
7091 "x_unicode_2_0_utf_7",
7093 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
7094 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
7096 "utf_16", "UTF_16LE", "ucs_2", "unicode",
7099 "unicodefffe", "utf_16be",
7106 * Returns the internal codepage, if the value of "int_code_page" is
7107 * 1 at entry, and we can not compute a suitable code page number,
7108 * returns the code page as a string
7110 ICALL_EXPORT MonoString*
7111 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
7116 char *codepage = NULL;
7118 int want_name = *int_code_page;
7121 *int_code_page = -1;
7123 g_get_charset (&cset);
7124 c = codepage = strdup (cset);
7125 for (c = codepage; *c; c++){
7126 if (isascii (*c) && isalpha (*c))
7131 /* g_print ("charset: %s\n", cset); */
7133 /* handle some common aliases */
7136 for (i = 0; p != 0; ){
7139 p = encodings [++i];
7142 if (strcmp (p, codepage) == 0){
7143 *int_code_page = code;
7146 p = encodings [++i];
7149 if (strstr (codepage, "utf_8") != NULL)
7150 *int_code_page |= 0x10000000;
7153 if (want_name && *int_code_page == -1)
7154 return mono_string_new (mono_domain_get (), cset);
7159 ICALL_EXPORT MonoBoolean
7160 ves_icall_System_Environment_get_HasShutdownStarted (void)
7162 if (mono_runtime_is_shutting_down ())
7165 if (mono_domain_is_unloading (mono_domain_get ()))
7172 ves_icall_System_Environment_BroadcastSettingChange (void)
7175 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)NULL, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
7181 ves_icall_System_Environment_get_TickCount (void)
7183 /* this will overflow after ~24 days */
7184 return (gint32) (mono_msec_boottime () & 0xffffffff);
7188 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
7193 #ifndef DISABLE_REMOTING
7194 ICALL_EXPORT MonoBoolean
7195 ves_icall_IsTransparentProxy (MonoObject *proxy)
7200 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
7206 ICALL_EXPORT MonoReflectionMethod *
7207 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
7208 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
7210 MonoReflectionMethod *ret = NULL;
7215 MonoMethod **vtable;
7216 MonoMethod *res = NULL;
7218 MONO_CHECK_ARG_NULL (rtype, NULL);
7219 MONO_CHECK_ARG_NULL (rmethod, NULL);
7221 method = rmethod->method;
7222 klass = mono_class_from_mono_type (rtype->type);
7223 mono_class_init_checked (klass, &error);
7224 if (mono_error_set_pending_exception (&error))
7227 if (MONO_CLASS_IS_INTERFACE (klass))
7230 if (method->flags & METHOD_ATTRIBUTE_STATIC)
7233 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
7234 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
7240 mono_class_setup_vtable (klass);
7241 vtable = klass->vtable;
7243 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
7244 gboolean variance_used = FALSE;
7245 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
7246 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
7248 res = vtable [offs + method->slot];
7250 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
7253 if (method->slot != -1)
7254 res = vtable [method->slot];
7260 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
7261 mono_error_set_pending_exception (&error);
7266 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7272 klass = mono_class_from_mono_type (type->type);
7273 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
7274 if (!is_ok (&error)) {
7275 mono_error_set_pending_exception (&error);
7279 mono_vtable_set_is_remote (vtable, enable);
7282 #else /* DISABLE_REMOTING */
7285 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
7287 g_assert_not_reached ();
7292 ICALL_EXPORT MonoObject *
7293 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
7300 domain = mono_object_domain (type);
7301 klass = mono_class_from_mono_type (type->type);
7302 mono_class_init_checked (klass, &error);
7303 if (mono_error_set_pending_exception (&error))
7306 if (MONO_CLASS_IS_INTERFACE (klass) || (klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
7307 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
7311 if (klass->rank >= 1) {
7312 g_assert (klass->rank == 1);
7313 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
7314 mono_error_set_pending_exception (&error);
7317 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
7318 if (!is_ok (&error)) {
7319 mono_error_set_pending_exception (&error);
7322 /* Bypass remoting object creation check */
7323 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7324 mono_error_set_pending_exception (&error);
7330 ICALL_EXPORT MonoString *
7331 ves_icall_System_IO_get_temp_path (void)
7333 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
7336 #ifndef PLATFORM_NO_DRIVEINFO
7337 ICALL_EXPORT MonoBoolean
7338 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7339 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7343 ULARGE_INTEGER wapi_free_bytes_avail;
7344 ULARGE_INTEGER wapi_total_number_of_bytes;
7345 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7347 *error = ERROR_SUCCESS;
7348 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7349 &wapi_total_number_of_free_bytes);
7352 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7353 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7354 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7356 *free_bytes_avail = 0;
7357 *total_number_of_bytes = 0;
7358 *total_number_of_free_bytes = 0;
7359 *error = GetLastError ();
7365 ICALL_EXPORT guint32
7366 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7368 return GetDriveType (mono_string_chars (root_path_name));
7372 ICALL_EXPORT gpointer
7373 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7376 gpointer result = mono_compile_method_checked (method, &error);
7377 mono_error_set_pending_exception (&error);
7381 ICALL_EXPORT MonoString *
7382 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7387 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7389 #if defined (HOST_WIN32)
7390 /* Avoid mixing '/' and '\\' */
7393 for (i = strlen (path) - 1; i >= 0; i--)
7394 if (path [i] == '/')
7398 mcpath = mono_string_new (mono_domain_get (), path);
7404 /* this is an icall */
7406 get_bundled_app_config (void)
7409 const gchar *app_config;
7412 gchar *config_file_name, *config_file_path;
7413 gsize len, config_file_path_length, config_ext_length;
7416 domain = mono_domain_get ();
7417 file = domain->setup->configuration_file;
7418 if (!file || file->length == 0)
7421 // Retrieve config file and remove the extension
7422 config_file_name = mono_string_to_utf8_checked (file, &error);
7423 if (mono_error_set_pending_exception (&error))
7425 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7426 if (!config_file_path)
7427 config_file_path = config_file_name;
7429 config_file_path_length = strlen (config_file_path);
7430 config_ext_length = strlen (".config");
7431 if (config_file_path_length <= config_ext_length)
7434 len = config_file_path_length - config_ext_length;
7435 module = (gchar *)g_malloc0 (len + 1);
7436 memcpy (module, config_file_path, len);
7437 // Get the config file from the module name
7438 app_config = mono_config_string_for_assembly_file (module);
7441 if (config_file_name != config_file_path)
7442 g_free (config_file_name);
7443 g_free (config_file_path);
7448 return mono_string_new (mono_domain_get (), app_config);
7452 get_bundled_machine_config (void)
7454 const gchar *machine_config;
7456 machine_config = mono_get_machine_config ();
7458 if (!machine_config)
7461 return mono_string_new (mono_domain_get (), machine_config);
7464 ICALL_EXPORT MonoString *
7465 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7470 path = g_path_get_dirname (mono_get_config_dir ());
7472 #if defined (HOST_WIN32)
7473 /* Avoid mixing '/' and '\\' */
7476 for (i = strlen (path) - 1; i >= 0; i--)
7477 if (path [i] == '/')
7481 ipath = mono_string_new (mono_domain_get (), path);
7487 ICALL_EXPORT gboolean
7488 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7490 MonoPEResourceDataEntry *entry;
7493 if (!assembly || !result || !size)
7498 image = assembly->assembly->image;
7499 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7503 *result = mono_image_rva_map (image, entry->rde_data_offset);
7508 *size = entry->rde_size;
7513 ICALL_EXPORT MonoBoolean
7514 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7516 return mono_is_debugger_attached ();
7519 ICALL_EXPORT MonoBoolean
7520 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7522 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7523 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7529 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7531 if (mono_get_runtime_callbacks ()->debug_log)
7532 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7536 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7538 #if defined (HOST_WIN32)
7539 OutputDebugString (mono_string_chars (message));
7541 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7545 /* Only used for value types */
7546 ICALL_EXPORT MonoObject *
7547 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7554 domain = mono_object_domain (type);
7555 klass = mono_class_from_mono_type (type->type);
7556 mono_class_init_checked (klass, &error);
7557 if (mono_error_set_pending_exception (&error))
7560 if (mono_class_is_nullable (klass))
7561 /* No arguments -> null */
7564 result = mono_object_new_checked (domain, klass, &error);
7565 mono_error_set_pending_exception (&error);
7569 ICALL_EXPORT MonoReflectionMethod *
7570 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7572 MonoReflectionMethod *ret = NULL;
7575 MonoClass *klass, *parent;
7576 MonoGenericContext *generic_inst = NULL;
7577 MonoMethod *method = m->method;
7578 MonoMethod *result = NULL;
7581 if (method->klass == NULL)
7584 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7585 MONO_CLASS_IS_INTERFACE (method->klass) ||
7586 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7589 slot = mono_method_get_vtable_slot (method);
7593 klass = method->klass;
7594 if (klass->generic_class) {
7595 generic_inst = mono_class_get_context (klass);
7596 klass = klass->generic_class->container_class;
7600 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7601 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7602 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7603 or klass is the generic container class and generic_inst is the instantiation.
7605 when we go to the parent, if the parent is an open constructed type, we need to
7606 replace the type parameters by the definitions from the generic_inst, and then take it
7607 apart again into the klass and the generic_inst.
7609 For cases like this:
7610 class C<T> : B<T, int> {
7611 public override void Foo () { ... }
7613 class B<U,V> : A<HashMap<U,V>> {
7614 public override void Foo () { ... }
7617 public virtual void Foo () { ... }
7620 if at each iteration the parent isn't open, we can skip inflating it. if at some
7621 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7624 MonoGenericContext *parent_inst = NULL;
7625 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7626 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7627 if (!mono_error_ok (&error)) {
7628 mono_error_set_pending_exception (&error);
7632 if (parent->generic_class) {
7633 parent_inst = mono_class_get_context (parent);
7634 parent = parent->generic_class->container_class;
7637 mono_class_setup_vtable (parent);
7638 if (parent->vtable_size <= slot)
7641 generic_inst = parent_inst;
7644 klass = klass->parent;
7647 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7648 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7649 if (!mono_error_ok (&error)) {
7650 mono_error_set_pending_exception (&error);
7654 generic_inst = NULL;
7656 if (klass->generic_class) {
7657 generic_inst = mono_class_get_context (klass);
7658 klass = klass->generic_class->container_class;
7664 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7665 if (!mono_error_ok (&error)) {
7666 mono_error_set_pending_exception (&error);
7671 if (klass == method->klass)
7674 /*This is possible if definition == FALSE.
7675 * Do it here to be really sure we don't read invalid memory.
7677 if (slot >= klass->vtable_size)
7680 mono_class_setup_vtable (klass);
7682 result = klass->vtable [slot];
7683 if (result == NULL) {
7684 /* It is an abstract method */
7685 gpointer iter = NULL;
7686 while ((result = mono_class_get_methods (klass, &iter)))
7687 if (result->slot == slot)
7694 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7695 mono_error_set_pending_exception (&error);
7699 ICALL_EXPORT MonoString*
7700 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7702 MonoMethod *method = m->method;
7704 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7709 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7711 iter->sig = *(MonoMethodSignature**)argsp;
7713 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7714 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7717 /* FIXME: it's not documented what start is exactly... */
7721 iter->args = argsp + sizeof (gpointer);
7723 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7725 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7728 ICALL_EXPORT MonoTypedRef
7729 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7731 guint32 i, arg_size;
7735 i = iter->sig->sentinelpos + iter->next_arg;
7737 g_assert (i < iter->sig->param_count);
7739 res.type = iter->sig->params [i];
7740 res.klass = mono_class_from_mono_type (res.type);
7741 arg_size = mono_type_stack_size (res.type, &align);
7742 #if defined(__arm__) || defined(__mips__)
7743 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7745 res.value = iter->args;
7746 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7747 /* Values are stored as 8 byte register sized objects, but 'value'
7748 * is dereferenced as a pointer in other routines.
7750 res.value = (char*)res.value + 4;
7752 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7753 if (arg_size <= sizeof (gpointer)) {
7755 int padding = arg_size - mono_type_size (res.type, &dummy);
7756 res.value = (guint8*)res.value + padding;
7759 iter->args = (char*)iter->args + arg_size;
7762 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7767 ICALL_EXPORT MonoTypedRef
7768 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7770 guint32 i, arg_size;
7774 i = iter->sig->sentinelpos + iter->next_arg;
7776 g_assert (i < iter->sig->param_count);
7778 while (i < iter->sig->param_count) {
7779 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7781 res.type = iter->sig->params [i];
7782 res.klass = mono_class_from_mono_type (res.type);
7783 /* FIXME: endianess issue... */
7784 arg_size = mono_type_stack_size (res.type, &align);
7785 #if defined(__arm__) || defined(__mips__)
7786 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7788 res.value = iter->args;
7789 iter->args = (char*)iter->args + arg_size;
7791 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7794 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7802 ICALL_EXPORT MonoType*
7803 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7807 i = iter->sig->sentinelpos + iter->next_arg;
7809 g_assert (i < iter->sig->param_count);
7811 return iter->sig->params [i];
7814 ICALL_EXPORT MonoObject*
7815 mono_TypedReference_ToObject (MonoTypedRef* tref)
7818 MonoObject *result = NULL;
7819 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7820 MonoObject** objp = (MonoObject **)tref->value;
7824 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7825 mono_error_set_pending_exception (&error);
7829 ICALL_EXPORT MonoTypedRef
7830 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7833 MonoReflectionField *f;
7835 MonoType *ftype = NULL;
7839 memset (&res, 0, sizeof (res));
7842 g_assert (mono_array_length (fields) > 0);
7844 klass = target->vtable->klass;
7846 for (i = 0; i < mono_array_length (fields); ++i) {
7847 f = mono_array_get (fields, MonoReflectionField*, i);
7849 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7852 if (f->field->parent != klass) {
7853 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7857 p = (guint8*)target + f->field->offset;
7859 p += f->field->offset - sizeof (MonoObject);
7860 klass = mono_class_from_mono_type (f->field->type);
7861 ftype = f->field->type;
7865 res.klass = mono_class_from_mono_type (ftype);
7872 prelink_method (MonoMethod *method, MonoError *error)
7874 const char *exc_class, *exc_arg;
7876 mono_error_init (error);
7877 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7879 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7881 mono_error_set_exception_instance (error,
7882 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7885 /* create the wrapper, too? */
7889 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7893 prelink_method (method->method, &error);
7894 mono_error_set_pending_exception (&error);
7898 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7901 MonoClass *klass = mono_class_from_mono_type (type->type);
7903 gpointer iter = NULL;
7905 mono_class_init_checked (klass, &error);
7906 if (mono_error_set_pending_exception (&error))
7909 while ((m = mono_class_get_methods (klass, &iter))) {
7910 prelink_method (m, &error);
7911 if (mono_error_set_pending_exception (&error))
7916 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7918 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7919 gint32 const **exponents,
7920 gunichar2 const **digitLowerTable,
7921 gunichar2 const **digitUpperTable,
7922 gint64 const **tenPowersList,
7923 gint32 const **decHexDigits)
7925 *mantissas = Formatter_MantissaBitsTable;
7926 *exponents = Formatter_TensExponentTable;
7927 *digitLowerTable = Formatter_DigitLowerTable;
7928 *digitUpperTable = Formatter_DigitUpperTable;
7929 *tenPowersList = Formatter_TenPowersList;
7930 *decHexDigits = Formatter_DecHexDigits;
7934 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7935 * and avoid useless allocations.
7938 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7940 MonoReflectionType *rt;
7944 mono_error_init (error);
7945 for (i = 0; i < type->num_mods; ++i) {
7946 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7951 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7952 return_val_if_nok (error, NULL);
7954 for (i = 0; i < type->num_mods; ++i) {
7955 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7956 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7957 return_val_if_nok (error, NULL);
7959 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7960 return_val_if_nok (error, NULL);
7962 mono_array_setref (res, count, rt);
7969 ICALL_EXPORT MonoArray*
7970 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7973 MonoType *type = param->ClassImpl->type;
7974 MonoClass *member_class = mono_object_class (param->MemberImpl);
7975 MonoMethod *method = NULL;
7978 MonoMethodSignature *sig;
7981 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7982 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7983 method = rmethod->method;
7984 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7985 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7986 if (!(method = prop->property->get))
7987 method = prop->property->set;
7990 char *type_name = mono_type_get_full_name (member_class);
7991 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7992 MonoException *ex = mono_get_exception_not_supported (msg);
7995 mono_set_pending_exception (ex);
7999 image = method->klass->image;
8000 pos = param->PositionImpl;
8001 sig = mono_method_signature (method);
8005 type = sig->params [pos];
8007 res = type_array_from_modifiers (image, type, optional, &error);
8008 mono_error_set_pending_exception (&error);
8013 get_property_type (MonoProperty *prop)
8015 MonoMethodSignature *sig;
8017 sig = mono_method_signature (prop->get);
8019 } else if (prop->set) {
8020 sig = mono_method_signature (prop->set);
8021 return sig->params [sig->param_count - 1];
8026 ICALL_EXPORT MonoArray*
8027 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
8030 MonoType *type = get_property_type (property->property);
8031 MonoImage *image = property->klass->image;
8036 res = type_array_from_modifiers (image, type, optional, &error);
8037 mono_error_set_pending_exception (&error);
8042 *Construct a MonoType suited to be used to decode a constant blob object.
8044 * @type is the target type which will be constructed
8045 * @blob_type is the blob type, for example, that comes from the constant table
8046 * @real_type is the expected constructed type.
8049 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
8051 type->type = blob_type;
8052 type->data.klass = NULL;
8053 if (blob_type == MONO_TYPE_CLASS)
8054 type->data.klass = mono_defaults.object_class;
8055 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
8056 /* For enums, we need to use the base type */
8057 type->type = MONO_TYPE_VALUETYPE;
8058 type->data.klass = mono_class_from_mono_type (real_type);
8060 type->data.klass = mono_class_from_mono_type (real_type);
8063 ICALL_EXPORT MonoObject*
8064 property_info_get_default_value (MonoReflectionProperty *property)
8068 MonoProperty *prop = property->property;
8069 MonoType *type = get_property_type (prop);
8070 MonoDomain *domain = mono_object_domain (property);
8071 MonoTypeEnum def_type;
8072 const char *def_value;
8075 mono_class_init (prop->parent);
8077 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
8078 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
8082 def_value = mono_class_get_property_default_value (prop, &def_type);
8084 mono_type_from_blob_type (&blob_type, def_type, type);
8085 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
8087 mono_error_set_pending_exception (&error);
8091 ICALL_EXPORT MonoBoolean
8092 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
8095 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
8096 MonoCustomAttrInfo *cinfo;
8099 mono_class_init_checked (attr_class, &error);
8100 if (mono_error_set_pending_exception (&error))
8103 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
8104 if (!is_ok (&error)) {
8105 mono_error_set_pending_exception (&error);
8110 found = mono_custom_attrs_has_attr (cinfo, attr_class);
8112 mono_custom_attrs_free (cinfo);
8116 ICALL_EXPORT MonoArray*
8117 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
8119 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
8124 mono_class_init_checked (attr_class, &error);
8125 if (mono_error_set_pending_exception (&error))
8129 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
8130 if (!mono_error_ok (&error)) {
8131 mono_error_set_pending_exception (&error);
8138 ICALL_EXPORT MonoArray*
8139 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
8143 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
8144 mono_error_set_pending_exception (&error);
8149 ICALL_EXPORT MonoString*
8150 ves_icall_Mono_Runtime_GetDisplayName (void)
8153 MonoString *display_name;
8155 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
8156 display_name = mono_string_new (mono_domain_get (), info);
8158 return display_name;
8161 ICALL_EXPORT MonoString*
8162 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
8165 MonoString *message;
8169 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
8170 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
8173 message = mono_string_new (mono_domain_get (), "Error looking up error string");
8175 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
8176 if (mono_error_set_pending_exception (&error))
8183 ICALL_EXPORT gpointer
8184 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
8186 return GetCurrentProcess ();
8189 ICALL_EXPORT MonoBoolean
8190 ves_icall_Microsoft_Win32_NativeMethods_GetExitCodeProcess (gpointer handle, gint32 *exitcode)
8192 return GetExitCodeProcess (handle, (guint32*) exitcode);
8195 ICALL_EXPORT MonoBoolean
8196 ves_icall_Microsoft_Win32_NativeMethods_CloseProcess (gpointer handle)
8198 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
8199 return CloseHandle (handle);
8201 return CloseProcess (handle);
8205 ICALL_EXPORT MonoBoolean
8206 ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint32 exitcode)
8208 return TerminateProcess (handle, exitcode);
8212 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
8214 return WaitForInputIdle (handle, milliseconds);
8217 ICALL_EXPORT MonoBoolean
8218 ves_icall_Microsoft_Win32_NativeMethods_GetProcessWorkingSetSize (gpointer handle, gsize *min, gsize *max)
8220 return GetProcessWorkingSetSize (handle, min, max);
8223 ICALL_EXPORT MonoBoolean
8224 ves_icall_Microsoft_Win32_NativeMethods_SetProcessWorkingSetSize (gpointer handle, gsize min, gsize max)
8226 return SetProcessWorkingSetSize (handle, min, max);
8229 ICALL_EXPORT MonoBoolean
8230 ves_icall_Microsoft_Win32_NativeMethods_GetProcessTimes (gpointer handle, gint64 *creationtime, gint64 *exittime, gint64 *kerneltime, gint64 *usertime)
8232 return GetProcessTimes (handle, (LPFILETIME) creationtime, (LPFILETIME) exittime, (LPFILETIME) kerneltime, (LPFILETIME) usertime);
8236 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
8238 return mono_process_current_pid ();
8242 ves_icall_Microsoft_Win32_NativeMethods_GetPriorityClass (gpointer handle)
8244 return GetPriorityClass (handle);
8247 ICALL_EXPORT MonoBoolean
8248 ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint32 priorityClass)
8250 return SetPriorityClass (handle, priorityClass);
8253 #ifndef DISABLE_ICALL_TABLES
8255 #define ICALL_TYPE(id,name,first)
8256 #define ICALL(id,name,func) Icall_ ## id,
8259 #include "metadata/icall-def.h"
8265 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8266 #define ICALL(id,name,func)
8268 #include "metadata/icall-def.h"
8274 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8275 #define ICALL(id,name,func)
8277 guint16 first_icall;
8280 static const IcallTypeDesc
8281 icall_type_descs [] = {
8282 #include "metadata/icall-def.h"
8286 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8289 #define ICALL_TYPE(id,name,first)
8292 #ifdef HAVE_ARRAY_ELEM_INIT
8293 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8294 #define MSGSTRFIELD1(line) str##line
8296 static const struct msgstrtn_t {
8297 #define ICALL(id,name,func)
8299 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8300 #include "metadata/icall-def.h"
8302 } icall_type_names_str = {
8303 #define ICALL_TYPE(id,name,first) (name),
8304 #include "metadata/icall-def.h"
8307 static const guint16 icall_type_names_idx [] = {
8308 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8309 #include "metadata/icall-def.h"
8312 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8314 static const struct msgstr_t {
8316 #define ICALL_TYPE(id,name,first)
8317 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8318 #include "metadata/icall-def.h"
8320 } icall_names_str = {
8321 #define ICALL(id,name,func) (name),
8322 #include "metadata/icall-def.h"
8325 static const guint16 icall_names_idx [] = {
8326 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8327 #include "metadata/icall-def.h"
8330 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8336 #define ICALL_TYPE(id,name,first) name,
8337 #define ICALL(id,name,func)
8338 static const char* const
8339 icall_type_names [] = {
8340 #include "metadata/icall-def.h"
8344 #define icall_type_name_get(id) (icall_type_names [(id)])
8348 #define ICALL_TYPE(id,name,first)
8349 #define ICALL(id,name,func) name,
8350 static const char* const
8352 #include "metadata/icall-def.h"
8355 #define icall_name_get(id) icall_names [(id)]
8357 #endif /* !HAVE_ARRAY_ELEM_INIT */
8361 #define ICALL_TYPE(id,name,first)
8362 #define ICALL(id,name,func) func,
8363 static const gconstpointer
8364 icall_functions [] = {
8365 #include "metadata/icall-def.h"
8369 #ifdef ENABLE_ICALL_SYMBOL_MAP
8372 #define ICALL_TYPE(id,name,first)
8373 #define ICALL(id,name,func) #func,
8374 static const gconstpointer
8375 icall_symbols [] = {
8376 #include "metadata/icall-def.h"
8381 #endif /* DISABLE_ICALL_TABLES */
8383 static mono_mutex_t icall_mutex;
8384 static GHashTable *icall_hash = NULL;
8385 static GHashTable *jit_icall_hash_name = NULL;
8386 static GHashTable *jit_icall_hash_addr = NULL;
8389 mono_icall_init (void)
8391 #ifndef DISABLE_ICALL_TABLES
8394 /* check that tables are sorted: disable in release */
8397 const char *prev_class = NULL;
8398 const char *prev_method;
8400 for (i = 0; i < Icall_type_num; ++i) {
8401 const IcallTypeDesc *desc;
8404 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8405 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8406 prev_class = icall_type_name_get (i);
8407 desc = &icall_type_descs [i];
8408 num_icalls = icall_desc_num_icalls (desc);
8409 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8410 for (j = 0; j < num_icalls; ++j) {
8411 const char *methodn = icall_name_get (desc->first_icall + j);
8412 if (prev_method && strcmp (prev_method, methodn) >= 0)
8413 g_print ("method %s should come before method %s\n", methodn, prev_method);
8414 prev_method = methodn;
8420 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8421 mono_os_mutex_init (&icall_mutex);
8425 mono_icall_lock (void)
8427 mono_locks_os_acquire (&icall_mutex, IcallLock);
8431 mono_icall_unlock (void)
8433 mono_locks_os_release (&icall_mutex, IcallLock);
8437 mono_icall_cleanup (void)
8439 g_hash_table_destroy (icall_hash);
8440 g_hash_table_destroy (jit_icall_hash_name);
8441 g_hash_table_destroy (jit_icall_hash_addr);
8442 mono_os_mutex_destroy (&icall_mutex);
8446 * mono_add_internal_call:
8447 * @name: method specification to surface to the managed world
8448 * @method: pointer to a C method to invoke when the method is called
8450 * This method surfaces the C function pointed by @method as a method
8451 * that has been surfaced in managed code with the method specified in
8452 * @name as an internal call.
8454 * Internal calls are surfaced to all app domains loaded and they are
8455 * accessibly by a type with the specified name.
8457 * You must provide a fully qualified type name, that is namespaces
8458 * and type name, followed by a colon and the method name, with an
8459 * optional signature to bind.
8461 * For example, the following are all valid declarations:
8463 * "MyApp.Services.ScriptService:Accelerate"
8464 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8466 * You use method parameters in cases where there might be more than
8467 * one surface method to managed code. That way you can register different
8468 * internal calls for different method overloads.
8470 * The internal calls are invoked with no marshalling. This means that .NET
8471 * types like System.String are exposed as `MonoString *` parameters. This is
8472 * different than the way that strings are surfaced in P/Invoke.
8474 * For more information on how the parameters are marshalled, see the
8475 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8478 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8479 * reference for more information on the format of method descriptions.
8482 mono_add_internal_call (const char *name, gconstpointer method)
8486 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8488 mono_icall_unlock ();
8491 #ifndef DISABLE_ICALL_TABLES
8493 #ifdef HAVE_ARRAY_ELEM_INIT
8495 compare_method_imap (const void *key, const void *elem)
8497 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8498 return strcmp (key, method_name);
8502 find_method_icall (const IcallTypeDesc *imap, const char *name)
8504 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);
8507 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
8511 compare_class_imap (const void *key, const void *elem)
8513 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8514 return strcmp (key, class_name);
8517 static const IcallTypeDesc*
8518 find_class_icalls (const char *name)
8520 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);
8523 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8526 #else /* HAVE_ARRAY_ELEM_INIT */
8529 compare_method_imap (const void *key, const void *elem)
8531 const char** method_name = (const char**)elem;
8532 return strcmp (key, *method_name);
8536 find_method_icall (const IcallTypeDesc *imap, const char *name)
8538 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8541 return (gpointer)icall_functions [(nameslot - icall_names)];
8545 compare_class_imap (const void *key, const void *elem)
8547 const char** class_name = (const char**)elem;
8548 return strcmp (key, *class_name);
8551 static const IcallTypeDesc*
8552 find_class_icalls (const char *name)
8554 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8557 return &icall_type_descs [nameslot - icall_type_names];
8560 #endif /* HAVE_ARRAY_ELEM_INIT */
8562 #endif /* DISABLE_ICALL_TABLES */
8565 * we should probably export this as an helper (handle nested types).
8566 * Returns the number of chars written in buf.
8569 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8571 int nspacelen, cnamelen;
8572 nspacelen = strlen (klass->name_space);
8573 cnamelen = strlen (klass->name);
8574 if (nspacelen + cnamelen + 2 > bufsize)
8577 memcpy (buf, klass->name_space, nspacelen);
8578 buf [nspacelen ++] = '.';
8580 memcpy (buf + nspacelen, klass->name, cnamelen);
8581 buf [nspacelen + cnamelen] = 0;
8582 return nspacelen + cnamelen;
8585 #ifdef DISABLE_ICALL_TABLES
8587 no_icall_table (void)
8589 g_assert_not_reached ();
8594 mono_lookup_internal_call (MonoMethod *method)
8599 int typelen = 0, mlen, siglen;
8601 #ifndef DISABLE_ICALL_TABLES
8602 const IcallTypeDesc *imap = NULL;
8605 g_assert (method != NULL);
8607 if (method->is_inflated)
8608 method = ((MonoMethodInflated *) method)->declaring;
8610 if (method->klass->nested_in) {
8611 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8615 mname [pos++] = '/';
8618 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8624 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8629 #ifndef DISABLE_ICALL_TABLES
8630 imap = find_class_icalls (mname);
8633 mname [typelen] = ':';
8634 mname [typelen + 1] = ':';
8636 mlen = strlen (method->name);
8637 memcpy (mname + typelen + 2, method->name, mlen);
8638 sigstart = mname + typelen + 2 + mlen;
8641 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8642 siglen = strlen (tmpsig);
8643 if (typelen + mlen + siglen + 6 > sizeof (mname))
8646 memcpy (sigstart + 1, tmpsig, siglen);
8647 sigstart [siglen + 1] = ')';
8648 sigstart [siglen + 2] = 0;
8653 res = g_hash_table_lookup (icall_hash, mname);
8655 mono_icall_unlock ();;
8658 /* try without signature */
8660 res = g_hash_table_lookup (icall_hash, mname);
8662 mono_icall_unlock ();
8666 #ifdef DISABLE_ICALL_TABLES
8667 mono_icall_unlock ();
8668 /* Fail only when the result is actually used */
8669 /* mono_marshal_get_native_wrapper () depends on this */
8670 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8671 return ves_icall_System_String_ctor_RedirectToCreateString;
8673 return no_icall_table;
8675 /* it wasn't found in the static call tables */
8677 mono_icall_unlock ();
8680 res = find_method_icall (imap, sigstart - mlen);
8682 mono_icall_unlock ();
8685 /* try _with_ signature */
8687 res = find_method_icall (imap, sigstart - mlen);
8689 mono_icall_unlock ();
8693 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8694 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8695 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8696 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8697 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");
8698 g_print ("If you see other errors or faults after this message they are probably related\n");
8699 g_print ("and you need to fix your mono install first.\n");
8701 mono_icall_unlock ();
8707 #ifdef ENABLE_ICALL_SYMBOL_MAP
8709 func_cmp (gconstpointer key, gconstpointer p)
8711 return (gsize)key - (gsize)*(gsize*)p;
8716 * mono_lookup_icall_symbol:
8718 * Given the icall METHOD, returns its C symbol.
8721 mono_lookup_icall_symbol (MonoMethod *m)
8723 #ifdef DISABLE_ICALL_TABLES
8724 g_assert_not_reached ();
8727 #ifdef ENABLE_ICALL_SYMBOL_MAP
8731 static gconstpointer *functions_sorted;
8732 static const char**symbols_sorted;
8733 static gboolean inited;
8738 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8739 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8740 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8741 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8742 /* Bubble sort the two arrays */
8746 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8747 if (functions_sorted [i] > functions_sorted [i + 1]) {
8750 tmp = functions_sorted [i];
8751 functions_sorted [i] = functions_sorted [i + 1];
8752 functions_sorted [i + 1] = tmp;
8753 tmp = symbols_sorted [i];
8754 symbols_sorted [i] = symbols_sorted [i + 1];
8755 symbols_sorted [i + 1] = tmp;
8762 func = mono_lookup_internal_call (m);
8765 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8769 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8771 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8772 g_assert_not_reached ();
8779 type_from_typename (char *type_name)
8781 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8783 if (!strcmp (type_name, "int"))
8784 klass = mono_defaults.int_class;
8785 else if (!strcmp (type_name, "ptr"))
8786 klass = mono_defaults.int_class;
8787 else if (!strcmp (type_name, "void"))
8788 klass = mono_defaults.void_class;
8789 else if (!strcmp (type_name, "int32"))
8790 klass = mono_defaults.int32_class;
8791 else if (!strcmp (type_name, "uint32"))
8792 klass = mono_defaults.uint32_class;
8793 else if (!strcmp (type_name, "int8"))
8794 klass = mono_defaults.sbyte_class;
8795 else if (!strcmp (type_name, "uint8"))
8796 klass = mono_defaults.byte_class;
8797 else if (!strcmp (type_name, "int16"))
8798 klass = mono_defaults.int16_class;
8799 else if (!strcmp (type_name, "uint16"))
8800 klass = mono_defaults.uint16_class;
8801 else if (!strcmp (type_name, "long"))
8802 klass = mono_defaults.int64_class;
8803 else if (!strcmp (type_name, "ulong"))
8804 klass = mono_defaults.uint64_class;
8805 else if (!strcmp (type_name, "float"))
8806 klass = mono_defaults.single_class;
8807 else if (!strcmp (type_name, "double"))
8808 klass = mono_defaults.double_class;
8809 else if (!strcmp (type_name, "object"))
8810 klass = mono_defaults.object_class;
8811 else if (!strcmp (type_name, "obj"))
8812 klass = mono_defaults.object_class;
8813 else if (!strcmp (type_name, "string"))
8814 klass = mono_defaults.string_class;
8815 else if (!strcmp (type_name, "bool"))
8816 klass = mono_defaults.boolean_class;
8817 else if (!strcmp (type_name, "boolean"))
8818 klass = mono_defaults.boolean_class;
8820 g_error ("%s", type_name);
8821 g_assert_not_reached ();
8823 return &klass->byval_arg;
8827 * LOCKING: Take the corlib image lock.
8829 MonoMethodSignature*
8830 mono_create_icall_signature (const char *sigstr)
8835 MonoMethodSignature *res, *res2;
8836 MonoImage *corlib = mono_defaults.corlib;
8838 mono_image_lock (corlib);
8839 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8840 mono_image_unlock (corlib);
8845 parts = g_strsplit (sigstr, " ", 256);
8854 res = mono_metadata_signature_alloc (corlib, len - 1);
8859 * Under windows, the default pinvoke calling convention is STDCALL but
8862 res->call_convention = MONO_CALL_C;
8865 res->ret = type_from_typename (parts [0]);
8866 for (i = 1; i < len; ++i) {
8867 res->params [i - 1] = type_from_typename (parts [i]);
8872 mono_image_lock (corlib);
8873 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8875 res = res2; /*Value is allocated in the image pool*/
8877 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8878 mono_image_unlock (corlib);
8884 mono_find_jit_icall_by_name (const char *name)
8886 MonoJitICallInfo *info;
8887 g_assert (jit_icall_hash_name);
8890 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8891 mono_icall_unlock ();
8896 mono_find_jit_icall_by_addr (gconstpointer addr)
8898 MonoJitICallInfo *info;
8899 g_assert (jit_icall_hash_addr);
8902 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8903 mono_icall_unlock ();
8909 * mono_get_jit_icall_info:
8911 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8912 * caller should access it while holding the icall lock.
8915 mono_get_jit_icall_info (void)
8917 return jit_icall_hash_name;
8921 * mono_lookup_jit_icall_symbol:
8923 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8926 mono_lookup_jit_icall_symbol (const char *name)
8928 MonoJitICallInfo *info;
8929 const char *res = NULL;
8932 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8934 res = info->c_symbol;
8935 mono_icall_unlock ();
8940 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8943 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8944 mono_icall_unlock ();
8948 * 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
8949 * icalls without wrappers in some cases.
8952 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8954 MonoJitICallInfo *info;
8961 if (!jit_icall_hash_name) {
8962 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8963 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8966 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8967 g_warning ("jit icall already defined \"%s\"\n", name);
8968 g_assert_not_reached ();
8971 info = g_new0 (MonoJitICallInfo, 1);
8976 info->c_symbol = c_symbol;
8977 info->no_raise = no_raise;
8980 info->wrapper = func;
8982 info->wrapper = NULL;
8985 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8986 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8988 mono_icall_unlock ();
8993 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8995 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);