5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool.h>
40 #include <mono/metadata/threadpool-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/w32file.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/w32socket.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/metadata-internals.h>
56 #include <mono/metadata/class-internals.h>
57 #include <mono/metadata/reflection-internals.h>
58 #include <mono/metadata/marshal.h>
59 #include <mono/metadata/gc-internals.h>
60 #include <mono/metadata/mono-gc.h>
61 #include <mono/metadata/rand.h>
62 #include <mono/metadata/sysmath.h>
63 #include <mono/metadata/appdomain-icalls.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/utils/monobitset.h>
89 #include <mono/utils/mono-time.h>
90 #include <mono/utils/mono-proclib.h>
91 #include <mono/utils/mono-string.h>
92 #include <mono/utils/mono-error-internals.h>
93 #include <mono/utils/mono-mmap.h>
94 #include <mono/utils/mono-io-portability.h>
95 #include <mono/utils/mono-digest.h>
96 #include <mono/utils/bsearch.h>
97 #include <mono/utils/mono-os-mutex.h>
98 #include <mono/utils/mono-threads.h>
99 #include <mono/metadata/w32error.h>
100 #include <mono/utils/w32api.h>
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 MonoStringHandle
ves_icall_System_Environment_GetOSVersionString (MonoError
*error
);
111 ICALL_EXPORT MonoReflectionAssemblyHandle
ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError
*error
);
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 array_set_value_impl (MonoArrayHandle arr
, MonoObjectHandle value
, guint32 pos
, MonoError
*error
);
124 static MonoArrayHandle
125 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
, MonoError
*error
);
127 static inline MonoBoolean
128 is_generic_parameter (MonoType
*type
)
130 return !type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
);
134 mono_class_init_checked (MonoClass
*klass
, MonoError
*error
)
138 if (!mono_class_init (klass
))
139 mono_error_set_for_class_failure (error
, klass
);
144 mono_icall_make_platform_path (gchar
*path
)
149 static inline const gchar
*
150 mono_icall_get_file_path_prefix (const gchar
*path
)
154 #endif /* HOST_WIN32 */
156 ICALL_EXPORT MonoObject
*
157 ves_icall_System_Array_GetValueImpl (MonoArray
*arr
, guint32 pos
)
163 MonoObject
*result
= NULL
;
165 ac
= (MonoClass
*)arr
->obj
.vtable
->klass
;
167 esize
= mono_array_element_size (ac
);
168 ea
= (gpointer
*)((char*)arr
->vector
+ (pos
* esize
));
170 if (ac
->element_class
->valuetype
) {
171 result
= mono_value_box_checked (arr
->obj
.vtable
->domain
, ac
->element_class
, ea
, &error
);
172 mono_error_set_pending_exception (&error
);
174 result
= (MonoObject
*)*ea
;
178 ICALL_EXPORT MonoObject
*
179 ves_icall_System_Array_GetValue (MonoArray
*arr
, MonoArray
*idxs
)
185 MONO_CHECK_ARG_NULL (idxs
, NULL
);
188 ic
= (MonoClass
*)io
->obj
.vtable
->klass
;
190 ac
= (MonoClass
*)arr
->obj
.vtable
->klass
;
192 g_assert (ic
->rank
== 1);
193 if (io
->bounds
!= NULL
|| io
->max_length
!= ac
->rank
) {
194 mono_set_pending_exception (mono_get_exception_argument (NULL
, NULL
));
198 ind
= (gint32
*)io
->vector
;
200 if (arr
->bounds
== NULL
) {
201 if (*ind
< 0 || *ind
>= arr
->max_length
) {
202 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
206 return ves_icall_System_Array_GetValueImpl (arr
, *ind
);
209 for (i
= 0; i
< ac
->rank
; i
++) {
210 if ((ind
[i
] < arr
->bounds
[i
].lower_bound
) ||
211 (ind
[i
] >= (mono_array_lower_bound_t
)arr
->bounds
[i
].length
+ arr
->bounds
[i
].lower_bound
)) {
212 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
217 pos
= ind
[0] - arr
->bounds
[0].lower_bound
;
218 for (i
= 1; i
< ac
->rank
; i
++)
219 pos
= pos
* arr
->bounds
[i
].length
+ ind
[i
] -
220 arr
->bounds
[i
].lower_bound
;
222 return ves_icall_System_Array_GetValueImpl (arr
, pos
);
226 ves_icall_System_Array_SetValueImpl (MonoArrayHandle arr
, MonoObjectHandle value
, guint32 pos
, MonoError
*error
)
229 array_set_value_impl (arr
, value
, pos
, error
);
233 array_set_value_impl (MonoArrayHandle arr
, MonoObjectHandle value
, guint32 pos
, MonoError
*error
)
235 MonoClass
*ac
, *vc
, *ec
;
244 uint32_t arr_gchandle
= 0;
245 uint32_t value_gchandle
= 0;
249 if (!MONO_HANDLE_IS_NULL (value
))
250 vc
= mono_handle_class (value
);
254 ac
= mono_handle_class (arr
);
255 ec
= ac
->element_class
;
257 esize
= mono_array_element_size (ac
);
258 ea
= mono_array_handle_pin_with_size (arr
, esize
, pos
, &arr_gchandle
);
260 if (mono_class_is_nullable (ec
)) {
261 mono_nullable_init_from_handle ((guint8
*)ea
, value
, ec
);
265 if (MONO_HANDLE_IS_NULL (value
)) {
266 mono_gc_bzero_atomic (ea
, esize
);
270 #define NO_WIDENING_CONVERSION G_STMT_START{ \
271 mono_error_set_argument (error, "value", "not a widening conversion"); \
275 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{ \
276 if (esize < vsize + (extra)) { \
277 mono_error_set_argument (error, "value", "not a widening conversion"); \
282 #define INVALID_CAST G_STMT_START{ \
283 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
284 mono_error_set_invalid_cast (error); \
288 /* Check element (destination) type. */
289 switch (ec
->byval_arg
.type
) {
290 case MONO_TYPE_STRING
:
291 switch (vc
->byval_arg
.type
) {
292 case MONO_TYPE_STRING
:
298 case MONO_TYPE_BOOLEAN
:
299 switch (vc
->byval_arg
.type
) {
300 case MONO_TYPE_BOOLEAN
:
313 NO_WIDENING_CONVERSION
;
322 MonoObjectHandle inst
= mono_object_handle_isinst (value
, ec
, error
);
325 gboolean castOk
= !MONO_HANDLE_IS_NULL (inst
);
327 if (!ec
->valuetype
) {
330 MONO_HANDLE_ARRAY_SETREF (arr
, pos
, value
);
335 va
= mono_object_handle_pin_unbox (value
, &value_gchandle
);
336 if (ec
->has_references
)
337 mono_value_copy (ea
, va
, ec
);
339 mono_gc_memmove_atomic (ea
, va
, esize
);
340 mono_gchandle_free (value_gchandle
);
348 va
= mono_object_handle_pin_unbox (value
, &value_gchandle
);
350 vsize
= mono_class_instance_size (vc
) - sizeof (MonoObject
);
352 et
= ec
->byval_arg
.type
;
353 if (et
== MONO_TYPE_VALUETYPE
&& ec
->byval_arg
.data
.klass
->enumtype
)
354 et
= mono_class_enum_basetype (ec
->byval_arg
.data
.klass
)->type
;
356 vt
= vc
->byval_arg
.type
;
357 if (vt
== MONO_TYPE_VALUETYPE
&& vc
->byval_arg
.data
.klass
->enumtype
)
358 vt
= mono_class_enum_basetype (vc
->byval_arg
.data
.klass
)->type
;
360 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
366 case MONO_TYPE_CHAR: \
367 CHECK_WIDENING_CONVERSION(0); \
368 *(etype *) ea = (etype) u64; \
370 /* You can't assign a signed value to an unsigned array. */ \
375 /* You can't assign a floating point number to an integer array. */ \
378 NO_WIDENING_CONVERSION; \
382 #define ASSIGN_SIGNED(etype) G_STMT_START{\
388 CHECK_WIDENING_CONVERSION(0); \
389 *(etype *) ea = (etype) i64; \
391 /* You can assign an unsigned value to a signed array if the array's */ \
392 /* element size is larger than the value size. */ \
397 case MONO_TYPE_CHAR: \
398 CHECK_WIDENING_CONVERSION(1); \
399 *(etype *) ea = (etype) u64; \
401 /* You can't assign a floating point number to an integer array. */ \
404 NO_WIDENING_CONVERSION; \
408 #define ASSIGN_REAL(etype) G_STMT_START{\
412 CHECK_WIDENING_CONVERSION(0); \
413 *(etype *) ea = (etype) r64; \
415 /* All integer values fit into a floating point array, so we don't */ \
416 /* need to CHECK_WIDENING_CONVERSION here. */ \
421 *(etype *) ea = (etype) i64; \
427 case MONO_TYPE_CHAR: \
428 *(etype *) ea = (etype) u64; \
435 u64
= *(guint8
*) va
;
438 u64
= *(guint16
*) va
;
441 u64
= *(guint32
*) va
;
444 u64
= *(guint64
*) va
;
450 i64
= *(gint16
*) va
;
453 i64
= *(gint32
*) va
;
456 i64
= *(gint64
*) va
;
459 r64
= *(gfloat
*) va
;
462 r64
= *(gdouble
*) va
;
465 u64
= *(guint16
*) va
;
467 case MONO_TYPE_BOOLEAN
:
468 /* Boolean is only compatible with itself. */
481 NO_WIDENING_CONVERSION
;
488 /* If we can't do a direct copy, let's try a widening conversion. */
491 ASSIGN_UNSIGNED (guint16
);
493 ASSIGN_UNSIGNED (guint8
);
495 ASSIGN_UNSIGNED (guint16
);
497 ASSIGN_UNSIGNED (guint32
);
499 ASSIGN_UNSIGNED (guint64
);
501 ASSIGN_SIGNED (gint8
);
503 ASSIGN_SIGNED (gint16
);
505 ASSIGN_SIGNED (gint32
);
507 ASSIGN_SIGNED (gint64
);
509 ASSIGN_REAL (gfloat
);
511 ASSIGN_REAL (gdouble
);
515 /* Not reached, INVALID_CAST does fall thru. */
516 g_assert_not_reached ();
519 #undef NO_WIDENING_CONVERSION
520 #undef CHECK_WIDENING_CONVERSION
521 #undef ASSIGN_UNSIGNED
526 mono_gchandle_free (arr_gchandle
);
528 mono_gchandle_free (value_gchandle
);
533 ves_icall_System_Array_SetValue (MonoArrayHandle arr
, MonoObjectHandle value
,
534 MonoArrayHandle idxs
, MonoError
*error
)
543 if (MONO_HANDLE_IS_NULL (idxs
)) {
544 mono_error_set_argument_null (error
, "idxs", "");
548 ic
= mono_handle_class (idxs
);
549 ac
= mono_handle_class (arr
);
551 g_assert (ic
->rank
== 1);
552 if (mono_handle_array_has_bounds (idxs
) || MONO_HANDLE_GETVAL (idxs
, max_length
) != ac
->rank
) {
553 mono_error_set_argument (error
, "idxs", "");
557 if (!mono_handle_array_has_bounds (arr
)) {
558 MONO_HANDLE_ARRAY_GETVAL (idx
, idxs
, gint32
, 0);
559 if (idx
< 0 || idx
>= MONO_HANDLE_GETVAL (arr
, max_length
)) {
560 mono_error_set_exception_instance (error
, mono_get_exception_index_out_of_range ());
564 array_set_value_impl (arr
, value
, idx
, error
);
568 for (i
= 0; i
< ac
->rank
; i
++) {
569 mono_handle_array_get_bounds_dim (arr
, i
, &dim
);
570 MONO_HANDLE_ARRAY_GETVAL (idx
, idxs
, gint32
, i
);
571 if ((idx
< dim
.lower_bound
) ||
572 (idx
>= (mono_array_lower_bound_t
)dim
.length
+ dim
.lower_bound
)) {
573 mono_error_set_exception_instance (error
, mono_get_exception_index_out_of_range ());
579 MONO_HANDLE_ARRAY_GETVAL (idx
, idxs
, gint32
, 0);
580 mono_handle_array_get_bounds_dim (arr
, 0, &dim
);
581 pos
= idx
- dim
.lower_bound
;
582 for (i
= 1; i
< ac
->rank
; i
++) {
583 mono_handle_array_get_bounds_dim (arr
, i
, &dim
);
584 MONO_HANDLE_ARRAY_GETVAL (idx
, idxs
, gint32
, i
);
585 pos
= pos
* dim
.length
+ idx
- dim
.lower_bound
;
588 array_set_value_impl (arr
, value
, pos
, error
);
591 ICALL_EXPORT MonoArray
*
592 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
595 MonoClass
*aklass
, *klass
;
598 gboolean bounded
= FALSE
;
600 MONO_CHECK_ARG_NULL (type
, NULL
);
601 MONO_CHECK_ARG_NULL (lengths
, NULL
);
603 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0, NULL
);
605 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
), NULL
);
607 for (i
= 0; i
< mono_array_length (lengths
); i
++) {
608 if (mono_array_get (lengths
, gint32
, i
) < 0) {
609 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL
));
614 klass
= mono_class_from_mono_type (type
->type
);
615 mono_class_init_checked (klass
, &error
);
616 if (mono_error_set_pending_exception (&error
))
619 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_VOID
) {
620 mono_set_pending_exception (mono_get_exception_not_supported ("Arrays of System.Void are not supported."));
624 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint32
, 0) != 0))
625 /* vectors are not the same as one dimensional arrays with no-zero bounds */
630 aklass
= mono_bounded_array_class_get (klass
, mono_array_length (lengths
), bounded
);
632 sizes
= (uintptr_t *)alloca (aklass
->rank
* sizeof(intptr_t) * 2);
633 for (i
= 0; i
< aklass
->rank
; ++i
) {
634 sizes
[i
] = mono_array_get (lengths
, guint32
, i
);
636 sizes
[i
+ aklass
->rank
] = mono_array_get (bounds
, gint32
, i
);
638 sizes
[i
+ aklass
->rank
] = 0;
641 array
= mono_array_new_full_checked (mono_object_domain (type
), aklass
, sizes
, (intptr_t*)sizes
+ aklass
->rank
, &error
);
642 mono_error_set_pending_exception (&error
);
647 ICALL_EXPORT MonoArray
*
648 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
651 MonoClass
*aklass
, *klass
;
654 gboolean bounded
= FALSE
;
656 MONO_CHECK_ARG_NULL (type
, NULL
);
657 MONO_CHECK_ARG_NULL (lengths
, NULL
);
659 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0, NULL
);
661 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
), NULL
);
663 for (i
= 0; i
< mono_array_length (lengths
); i
++) {
664 if ((mono_array_get (lengths
, gint64
, i
) < 0) ||
665 (mono_array_get (lengths
, gint64
, i
) > MONO_ARRAY_MAX_INDEX
)) {
666 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL
));
671 klass
= mono_class_from_mono_type (type
->type
);
672 mono_class_init_checked (klass
, &error
);
673 if (mono_error_set_pending_exception (&error
))
676 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint64
, 0) != 0))
677 /* vectors are not the same as one dimensional arrays with no-zero bounds */
682 aklass
= mono_bounded_array_class_get (klass
, mono_array_length (lengths
), bounded
);
684 sizes
= (uintptr_t *)alloca (aklass
->rank
* sizeof(intptr_t) * 2);
685 for (i
= 0; i
< aklass
->rank
; ++i
) {
686 sizes
[i
] = mono_array_get (lengths
, guint64
, i
);
688 sizes
[i
+ aklass
->rank
] = (mono_array_size_t
) mono_array_get (bounds
, guint64
, i
);
690 sizes
[i
+ aklass
->rank
] = 0;
693 array
= mono_array_new_full_checked (mono_object_domain (type
), aklass
, sizes
, (intptr_t*)sizes
+ aklass
->rank
, &error
);
694 mono_error_set_pending_exception (&error
);
700 ves_icall_System_Array_GetRank (MonoObject
*arr
)
702 return arr
->vtable
->klass
->rank
;
706 ves_icall_System_Array_GetLength (MonoArray
*arr
, gint32 dimension
)
708 gint32 rank
= arr
->obj
.vtable
->klass
->rank
;
711 if ((dimension
< 0) || (dimension
>= rank
)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr
->bounds
== NULL
)
717 length
= arr
->max_length
;
719 length
= arr
->bounds
[dimension
].length
;
721 #ifdef MONO_BIG_ARRAYS
722 if (length
> G_MAXINT32
) {
723 mono_set_pending_exception (mono_get_exception_overflow ());
731 ves_icall_System_Array_GetLongLength (MonoArray
*arr
, gint32 dimension
)
733 gint32 rank
= arr
->obj
.vtable
->klass
->rank
;
735 if ((dimension
< 0) || (dimension
>= rank
)) {
736 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
740 if (arr
->bounds
== NULL
)
741 return arr
->max_length
;
743 return arr
->bounds
[dimension
].length
;
747 ves_icall_System_Array_GetLowerBound (MonoArray
*arr
, gint32 dimension
)
749 gint32 rank
= arr
->obj
.vtable
->klass
->rank
;
751 if ((dimension
< 0) || (dimension
>= rank
)) {
752 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
756 if (arr
->bounds
== NULL
)
759 return arr
->bounds
[dimension
].lower_bound
;
763 ves_icall_System_Array_ClearInternal (MonoArray
*arr
, int idx
, int length
)
765 int sz
= mono_array_element_size (mono_object_class (arr
));
766 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr
, sz
, idx
), length
* sz
);
770 ICALL_EXPORT gboolean
771 ves_icall_System_Array_FastCopy (MonoArray
*source
, int source_idx
, MonoArray
* dest
, int dest_idx
, int length
)
776 MonoVTable
*src_vtable
;
777 MonoVTable
*dest_vtable
;
778 MonoClass
*src_class
;
779 MonoClass
*dest_class
;
781 src_vtable
= source
->obj
.vtable
;
782 dest_vtable
= dest
->obj
.vtable
;
784 if (src_vtable
->rank
!= dest_vtable
->rank
)
787 if (source
->bounds
|| dest
->bounds
)
790 /* there's no integer overflow since mono_array_length returns an unsigned integer */
791 if ((dest_idx
+ length
> mono_array_length_fast (dest
)) ||
792 (source_idx
+ length
> mono_array_length_fast (source
)))
795 src_class
= src_vtable
->klass
->element_class
;
796 dest_class
= dest_vtable
->klass
->element_class
;
799 * Handle common cases.
802 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
803 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
805 if (src_class
== mono_defaults
.object_class
&& dest_class
->valuetype
)
808 /* Check if we're copying a char[] <==> (u)short[] */
809 if (src_class
!= dest_class
) {
810 if (dest_class
->valuetype
|| dest_class
->enumtype
|| src_class
->valuetype
|| src_class
->enumtype
)
813 /* 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. */
814 if (!mono_class_is_subclass_of (src_class
, dest_class
, FALSE
))
818 if (dest_class
->valuetype
) {
819 element_size
= mono_array_element_size (source
->obj
.vtable
->klass
);
820 source_addr
= mono_array_addr_with_size_fast (source
, element_size
, source_idx
);
821 if (dest_class
->has_references
) {
822 mono_value_copy_array (dest
, dest_idx
, source_addr
, length
);
824 dest_addr
= mono_array_addr_with_size_fast (dest
, element_size
, dest_idx
);
825 mono_gc_memmove_atomic (dest_addr
, source_addr
, element_size
* length
);
828 mono_array_memcpy_refs_fast (dest
, dest_idx
, source
, source_idx
, length
);
835 ves_icall_System_Array_GetGenericValueImpl (MonoArray
*arr
, guint32 pos
, gpointer value
)
841 ac
= (MonoClass
*)arr
->obj
.vtable
->klass
;
843 esize
= mono_array_element_size (ac
);
844 ea
= (gpointer
*)((char*)arr
->vector
+ (pos
* esize
));
846 mono_gc_memmove_atomic (value
, ea
, esize
);
850 ves_icall_System_Array_SetGenericValueImpl (MonoArray
*arr
, guint32 pos
, gpointer value
)
856 ac
= (MonoClass
*)arr
->obj
.vtable
->klass
;
857 ec
= ac
->element_class
;
859 esize
= mono_array_element_size (ac
);
860 ea
= (gpointer
*)((char*)arr
->vector
+ (pos
* esize
));
862 if (MONO_TYPE_IS_REFERENCE (&ec
->byval_arg
)) {
863 g_assert (esize
== sizeof (gpointer
));
864 mono_gc_wbarrier_generic_store (ea
, *(MonoObject
**)value
);
866 g_assert (ec
->inited
);
867 g_assert (esize
== mono_class_value_size (ec
, NULL
));
868 if (ec
->has_references
)
869 mono_gc_wbarrier_value_copy (ea
, value
, 1, ec
);
871 mono_gc_memmove_atomic (ea
, value
, esize
);
876 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array
, MonoClassField
*field_handle
, MonoError
*error
)
880 MonoClass
*klass
= mono_handle_class (array
);
881 guint32 size
= mono_array_element_size (klass
);
882 MonoType
*type
= mono_type_get_underlying_type (&klass
->element_class
->byval_arg
);
884 const char *field_data
;
886 if (MONO_TYPE_IS_REFERENCE (type
) || type
->type
== MONO_TYPE_VALUETYPE
) {
887 mono_error_set_argument (error
, "array", "Cannot initialize array of non-primitive type");
891 if (!(field_handle
->type
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) {
892 mono_error_set_argument (error
, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle
));
896 size
*= MONO_HANDLE_GETVAL(array
, max_length
);
897 field_data
= mono_field_get_data (field_handle
);
899 if (size
> mono_type_size (field_handle
->type
, &align
)) {
900 mono_error_set_argument (error
, "field_handle", "Field not large enough to fill array");
904 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
906 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
907 guint ## n *src = (guint ## n *) field_data; \
909 nEnt = (size / sizeof(guint ## n)); \
911 for (i = 0; i < nEnt; i++) { \
912 data[i] = read ## n (&src[i]); \
916 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
918 switch (type
->type
) {
935 memcpy (mono_array_addr (MONO_HANDLE_RAW(array
), char, 0), field_data
, size
);
939 memcpy (mono_array_addr (MONO_HANDLE_RAW(array
), char, 0), field_data
, size
);
944 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
946 return offsetof (MonoString
, chars
);
949 ICALL_EXPORT MonoObject
*
950 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject
*obj
)
952 if ((obj
== NULL
) || (! (obj
->vtable
->klass
->valuetype
)))
956 MonoObject
*ret
= mono_object_clone_checked (obj
, &error
);
957 mono_error_set_pending_exception (&error
);
964 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType
*handle
)
970 MONO_CHECK_ARG_NULL (handle
,);
972 klass
= mono_class_from_mono_type (handle
);
973 MONO_CHECK_ARG (handle
, klass
,);
975 if (mono_class_is_gtd (klass
))
978 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, &error
);
979 if (!is_ok (&error
)) {
980 mono_error_set_pending_exception (&error
);
984 /* This will call the type constructor */
985 if (!mono_runtime_class_init_full (vtable
, &error
))
986 mono_error_set_pending_exception (&error
);
990 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage
*image
)
994 mono_image_check_for_module_cctor (image
);
995 if (image
->has_module_cctor
) {
996 MonoClass
*module_klass
= mono_class_get_checked (image
, MONO_TOKEN_TYPE_DEF
| 1, &error
);
997 if (!mono_error_ok (&error
)) {
998 mono_error_set_pending_exception (&error
);
1001 /*It's fine to raise the exception here*/
1002 MonoVTable
* vtable
= mono_class_vtable_full (mono_domain_get (), module_klass
, &error
);
1003 if (!is_ok (&error
)) {
1004 mono_error_set_pending_exception (&error
);
1007 if (!mono_runtime_class_init_full (vtable
, &error
))
1008 mono_error_set_pending_exception (&error
);
1012 ICALL_EXPORT MonoBoolean
1013 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
1015 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
1016 // It does not work on win32
1017 #elif defined(TARGET_ANDROID)
1024 MonoInternalThread
*thread
;
1026 mono_thread_info_get_stack_bounds (&stack_addr
, &stack_size
);
1027 /* if we have no info we are optimistic and assume there is enough room */
1031 thread
= mono_thread_internal_current ();
1032 // .net seems to check that at least 50% of stack is available
1033 min_size
= thread
->stack_size
/ 2;
1035 // TODO: It's not always set
1039 current
= (guint8
*)&stack_addr
;
1040 if (current
> stack_addr
) {
1041 if ((current
- stack_addr
) < min_size
)
1044 if (current
- (stack_addr
- stack_size
) < min_size
)
1051 ICALL_EXPORT MonoObject
*
1052 ves_icall_System_Object_MemberwiseClone (MonoObject
*this_obj
)
1055 MonoObject
*ret
= mono_object_clone_checked (this_obj
, &error
);
1056 mono_error_set_pending_exception (&error
);
1062 ves_icall_System_ValueType_InternalGetHashCode (MonoObject
*this_obj
, MonoArray
**fields
)
1066 MonoObject
**values
= NULL
;
1069 gint32 result
= (int)(gsize
)mono_defaults
.int32_class
;
1070 MonoClassField
* field
;
1073 klass
= mono_object_class (this_obj
);
1075 if (mono_class_num_fields (klass
) == 0)
1079 * Compute the starting value of the hashcode for fields of primitive
1080 * types, and return the remaining fields in an array to the managed side.
1081 * This way, we can avoid costly reflection operations in managed code.
1084 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1085 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1087 if (mono_field_is_deleted (field
))
1089 /* FIXME: Add more types */
1090 switch (field
->type
->type
) {
1092 result
^= *(gint32
*)((guint8
*)this_obj
+ field
->offset
);
1094 case MONO_TYPE_STRING
: {
1096 s
= *(MonoString
**)((guint8
*)this_obj
+ field
->offset
);
1098 result
^= mono_string_hash (s
);
1103 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
));
1104 o
= mono_field_get_value_object_checked (mono_object_domain (this_obj
), field
, this_obj
, &error
);
1105 if (!is_ok (&error
)) {
1106 mono_error_set_pending_exception (&error
);
1109 values
[count
++] = o
;
1115 MonoArray
*fields_arr
= mono_array_new_checked (mono_domain_get (), mono_defaults
.object_class
, count
, &error
);
1116 if (mono_error_set_pending_exception (&error
))
1118 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) fields_arr
);
1119 for (i
= 0; i
< count
; ++i
)
1120 mono_array_setref (*fields
, i
, values
[i
]);
1127 ICALL_EXPORT MonoBoolean
1128 ves_icall_System_ValueType_Equals (MonoObject
*this_obj
, MonoObject
*that
, MonoArray
**fields
)
1132 MonoObject
**values
= NULL
;
1134 MonoClassField
* field
;
1138 MONO_CHECK_ARG_NULL (that
, FALSE
);
1140 if (this_obj
->vtable
!= that
->vtable
)
1143 klass
= mono_object_class (this_obj
);
1145 if (klass
->enumtype
&& mono_class_enum_basetype (klass
) && mono_class_enum_basetype (klass
)->type
== MONO_TYPE_I4
)
1146 return (*(gint32
*)((guint8
*)this_obj
+ sizeof (MonoObject
)) == *(gint32
*)((guint8
*)that
+ sizeof (MonoObject
)));
1149 * Do the comparison for fields of primitive type and return a result if
1150 * possible. Otherwise, return the remaining fields in an array to the
1151 * managed side. This way, we can avoid costly reflection operations in
1156 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1157 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1159 if (mono_field_is_deleted (field
))
1161 /* FIXME: Add more types */
1162 switch (field
->type
->type
) {
1165 case MONO_TYPE_BOOLEAN
:
1166 if (*((guint8
*)this_obj
+ field
->offset
) != *((guint8
*)that
+ field
->offset
))
1171 case MONO_TYPE_CHAR
:
1172 if (*(gint16
*)((guint8
*)this_obj
+ field
->offset
) != *(gint16
*)((guint8
*)that
+ field
->offset
))
1177 if (*(gint32
*)((guint8
*)this_obj
+ field
->offset
) != *(gint32
*)((guint8
*)that
+ field
->offset
))
1182 if (*(gint64
*)((guint8
*)this_obj
+ field
->offset
) != *(gint64
*)((guint8
*)that
+ field
->offset
))
1186 if (*(float*)((guint8
*)this_obj
+ field
->offset
) != *(float*)((guint8
*)that
+ field
->offset
))
1190 if (*(double*)((guint8
*)this_obj
+ field
->offset
) != *(double*)((guint8
*)that
+ field
->offset
))
1195 case MONO_TYPE_STRING
: {
1196 MonoString
*s1
, *s2
;
1197 guint32 s1len
, s2len
;
1198 s1
= *(MonoString
**)((guint8
*)this_obj
+ field
->offset
);
1199 s2
= *(MonoString
**)((guint8
*)that
+ field
->offset
);
1202 if ((s1
== NULL
) || (s2
== NULL
))
1204 s1len
= mono_string_length (s1
);
1205 s2len
= mono_string_length (s2
);
1209 if (memcmp (mono_string_chars (s1
), mono_string_chars (s2
), s1len
* sizeof (gunichar2
)) != 0)
1215 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
) * 2);
1216 o
= mono_field_get_value_object_checked (mono_object_domain (this_obj
), field
, this_obj
, &error
);
1217 if (!is_ok (&error
)) {
1218 mono_error_set_pending_exception (&error
);
1221 values
[count
++] = o
;
1222 o
= mono_field_get_value_object_checked (mono_object_domain (this_obj
), field
, that
, &error
);
1223 if (!is_ok (&error
)) {
1224 mono_error_set_pending_exception (&error
);
1227 values
[count
++] = o
;
1230 if (klass
->enumtype
)
1231 /* enums only have one non-static field */
1237 MonoArray
*fields_arr
= mono_array_new_checked (mono_domain_get (), mono_defaults
.object_class
, count
, &error
);
1238 if (mono_error_set_pending_exception (&error
))
1240 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) fields_arr
);
1241 for (i
= 0; i
< count
; ++i
)
1242 mono_array_setref_fast (*fields
, i
, values
[i
]);
1249 ICALL_EXPORT MonoReflectionTypeHandle
1250 ves_icall_System_Object_GetType (MonoObjectHandle obj
, MonoError
*error
)
1253 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (obj
);
1254 MonoClass
*klass
= mono_handle_class (obj
);
1255 #ifndef DISABLE_REMOTING
1256 if (mono_class_is_transparent_proxy (klass
)) {
1257 MonoTransparentProxyHandle proxy_obj
= MONO_HANDLE_CAST (MonoTransparentProxy
, obj
);
1258 MonoRemoteClass
*remote_class
= MONO_HANDLE_GETVAL (proxy_obj
, remote_class
);
1259 MonoType
*proxy_type
= &remote_class
->proxy_class
->byval_arg
;
1260 return mono_type_get_object_handle (domain
, proxy_type
, error
);
1263 return mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
1267 get_executing (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1269 MonoMethod
**dest
= (MonoMethod
**)data
;
1271 /* skip unmanaged frames */
1276 if (!strcmp (m
->klass
->name_space
, "System.Reflection"))
1285 get_caller_no_reflection (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1287 MonoMethod
**dest
= (MonoMethod
**)data
;
1289 /* skip unmanaged frames */
1293 if (m
->wrapper_type
!= MONO_WRAPPER_NONE
)
1301 if (m
->klass
->image
== mono_defaults
.corlib
&& !strcmp (m
->klass
->name_space
, "System.Reflection"))
1312 get_caller_no_system_or_reflection (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1314 MonoMethod
**dest
= (MonoMethod
**)data
;
1316 /* skip unmanaged frames */
1320 if (m
->wrapper_type
!= MONO_WRAPPER_NONE
)
1328 if (m
->klass
->image
== mono_defaults
.corlib
&& ((!strcmp (m
->klass
->name_space
, "System.Reflection"))
1329 || (!strcmp (m
->klass
->name_space
, "System"))))
1339 static MonoReflectionTypeHandle
1340 type_from_parsed_name (MonoTypeNameParse
*info
, MonoBoolean ignoreCase
, MonoAssembly
**caller_assembly
, MonoError
*error
)
1342 MonoMethod
*m
, *dest
;
1344 MonoType
*type
= NULL
;
1345 MonoAssembly
*assembly
= NULL
;
1346 gboolean type_resolve
= FALSE
;
1347 MonoImage
*rootimage
= NULL
;
1352 * We must compute the calling assembly as type loading must happen under a metadata context.
1353 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1354 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1356 m
= mono_method_get_last_managed ();
1358 if (m
&& m
->klass
->image
!= mono_defaults
.corlib
) {
1359 /* Happens with inlining */
1361 /* Ugly hack: type_from_parsed_name is called from
1362 * System.Type.internal_from_name, which is called most
1363 * directly from System.Type.GetType(string,bool,bool) but
1364 * also indirectly from places such as
1365 * System.Type.GetType(string,func,func) (via
1366 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1367 * so we need to skip over all of those to find the true caller.
1369 * It would be nice if we had stack marks.
1371 mono_stack_walk_no_il (get_caller_no_system_or_reflection
, &dest
);
1377 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1378 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1379 * to crash. This only seems to happen in some strange remoting
1380 * scenarios and I was unable to figure out what's happening there.
1381 * Dec 10, 2005 - Martin.
1385 assembly
= dest
->klass
->image
->assembly
;
1386 type_resolve
= TRUE
;
1387 rootimage
= assembly
->image
;
1389 g_warning (G_STRLOC
);
1391 *caller_assembly
= assembly
;
1393 if (info
->assembly
.name
)
1394 assembly
= mono_assembly_load (&info
->assembly
, assembly
? assembly
->basedir
: NULL
, NULL
);
1397 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1398 type
= mono_reflection_get_type_checked (rootimage
, assembly
->image
, info
, ignoreCase
, &type_resolve
, error
);
1404 // Say we're looking for System.Generic.Dict<int, Local>
1405 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1406 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1407 // is messed up when we go to construct the Local as the type arg...
1409 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1410 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1411 if (!info
->assembly
.name
&& !type
) {
1413 type
= mono_reflection_get_type_checked (rootimage
, NULL
, info
, ignoreCase
, &type_resolve
, error
);
1417 if (assembly
&& !type
&& type_resolve
) {
1418 type_resolve
= FALSE
; /* This will invoke TypeResolve if not done in the first 'if' */
1419 type
= mono_reflection_get_type_checked (rootimage
, assembly
->image
, info
, ignoreCase
, &type_resolve
, error
);
1427 return mono_type_get_object_handle (mono_domain_get (), type
, error
);
1429 return MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1432 ICALL_EXPORT MonoReflectionTypeHandle
1433 ves_icall_System_Type_internal_from_name (MonoStringHandle name
,
1434 MonoBoolean throwOnError
,
1435 MonoBoolean ignoreCase
,
1439 MonoTypeNameParse info
;
1441 MonoAssembly
*caller_assembly
;
1442 MonoReflectionTypeHandle type
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1444 char *str
= mono_string_handle_to_utf8 (name
, error
);
1448 parsedOk
= mono_reflection_parse_type (str
, &info
);
1450 /* mono_reflection_parse_type() mangles the string */
1452 mono_reflection_free_type_info (&info
);
1454 mono_error_set_argument (error
, "typeName", "failed parse: %s", str
);
1458 MONO_HANDLE_ASSIGN (type
, type_from_parsed_name (&info
, ignoreCase
, &caller_assembly
, error
));
1460 if (!is_ok (error
)) {
1461 mono_reflection_free_type_info (&info
);
1465 if (MONO_HANDLE_IS_NULL (type
)) {
1467 char *tname
= info
.name_space
? g_strdup_printf ("%s.%s", info
.name_space
, info
.name
) : g_strdup (info
.name
);
1469 if (info
.assembly
.name
)
1470 aname
= mono_stringify_assembly_name (&info
.assembly
);
1471 else if (caller_assembly
)
1472 aname
= mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly
));
1474 aname
= g_strdup ("");
1475 mono_error_set_type_load_name (error
, tname
, aname
, "");
1477 mono_reflection_free_type_info (&info
);
1483 if (!is_ok (error
)) {
1485 mono_error_cleanup (error
);
1486 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
1493 ICALL_EXPORT MonoReflectionTypeHandle
1494 ves_icall_System_Type_internal_from_handle (MonoType
*handle
, MonoError
*error
)
1497 MonoDomain
*domain
= mono_domain_get ();
1499 return mono_type_get_object_handle (domain
, handle
, error
);
1502 ICALL_EXPORT MonoType
*
1503 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass
*klass
)
1505 return mono_class_get_type (klass
);
1509 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray
*ptr_array
)
1511 g_ptr_array_free (ptr_array
, TRUE
);
1515 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str
)
1521 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString
*s
)
1524 char *res
= mono_string_to_utf8_checked (s
, &error
);
1525 mono_error_set_pending_exception (&error
);
1529 /* System.TypeCode */
1548 TYPECODE_STRING
= 18
1551 ICALL_EXPORT guint32
1552 ves_icall_type_GetTypeCodeInternal (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
1555 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
1559 return TYPECODE_OBJECT
;
1563 case MONO_TYPE_VOID
:
1564 return TYPECODE_OBJECT
;
1565 case MONO_TYPE_BOOLEAN
:
1566 return TYPECODE_BOOLEAN
;
1568 return TYPECODE_BYTE
;
1570 return TYPECODE_SBYTE
;
1572 return TYPECODE_UINT16
;
1574 return TYPECODE_INT16
;
1575 case MONO_TYPE_CHAR
:
1576 return TYPECODE_CHAR
;
1580 return TYPECODE_OBJECT
;
1582 return TYPECODE_UINT32
;
1584 return TYPECODE_INT32
;
1586 return TYPECODE_UINT64
;
1588 return TYPECODE_INT64
;
1590 return TYPECODE_SINGLE
;
1592 return TYPECODE_DOUBLE
;
1593 case MONO_TYPE_VALUETYPE
: {
1594 MonoClass
*klass
= type
->data
.klass
;
1596 if (klass
->enumtype
) {
1597 t
= mono_class_enum_basetype (klass
)->type
;
1599 } else if (mono_is_corlib_image (klass
->image
)) {
1600 if (strcmp (klass
->name_space
, "System") == 0) {
1601 if (strcmp (klass
->name
, "Decimal") == 0)
1602 return TYPECODE_DECIMAL
;
1603 else if (strcmp (klass
->name
, "DateTime") == 0)
1604 return TYPECODE_DATETIME
;
1607 return TYPECODE_OBJECT
;
1609 case MONO_TYPE_STRING
:
1610 return TYPECODE_STRING
;
1611 case MONO_TYPE_SZARRAY
:
1612 case MONO_TYPE_ARRAY
:
1613 case MONO_TYPE_OBJECT
:
1615 case MONO_TYPE_MVAR
:
1616 case MONO_TYPE_TYPEDBYREF
:
1617 return TYPECODE_OBJECT
;
1618 case MONO_TYPE_CLASS
:
1620 MonoClass
*klass
= type
->data
.klass
;
1621 if (klass
->image
== mono_defaults
.corlib
&& strcmp (klass
->name_space
, "System") == 0) {
1622 if (strcmp (klass
->name
, "DBNull") == 0)
1623 return TYPECODE_DBNULL
;
1626 return TYPECODE_OBJECT
;
1627 case MONO_TYPE_GENERICINST
:
1628 return TYPECODE_OBJECT
;
1630 g_error ("type 0x%02x not handled in GetTypeCode()", t
);
1636 mono_type_get_underlying_type_ignore_byref (MonoType
*type
)
1638 if (type
->type
== MONO_TYPE_VALUETYPE
&& type
->data
.klass
->enumtype
)
1639 return mono_class_enum_basetype (type
->data
.klass
);
1640 if (type
->type
== MONO_TYPE_GENERICINST
&& type
->data
.generic_class
->container_class
->enumtype
)
1641 return mono_class_enum_basetype (type
->data
.generic_class
->container_class
);
1645 ICALL_EXPORT guint32
1646 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionTypeHandle ref_type
, MonoReflectionTypeHandle ref_c
, MonoError
*error
)
1650 g_assert (!MONO_HANDLE_IS_NULL (ref_type
));
1652 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
1653 MonoClass
*klass
= mono_class_from_mono_type (type
);
1654 MonoType
*ctype
= MONO_HANDLE_GETVAL (ref_c
, type
);
1655 MonoClass
*klassc
= mono_class_from_mono_type (ctype
);
1657 if (type
->byref
^ ctype
->byref
)
1661 MonoType
*t
= mono_type_get_underlying_type_ignore_byref (type
);
1662 MonoType
*ot
= mono_type_get_underlying_type_ignore_byref (ctype
);
1664 klass
= mono_class_from_mono_type (t
);
1665 klassc
= mono_class_from_mono_type (ot
);
1667 if (mono_type_is_primitive (t
)) {
1668 return mono_type_is_primitive (ot
) && klass
->instance_size
== klassc
->instance_size
;
1669 } else if (t
->type
== MONO_TYPE_VAR
|| t
->type
== MONO_TYPE_MVAR
) {
1670 return t
->type
== ot
->type
&& t
->data
.generic_param
->num
== ot
->data
.generic_param
->num
;
1671 } else if (t
->type
== MONO_TYPE_PTR
|| t
->type
== MONO_TYPE_FNPTR
) {
1672 return t
->type
== ot
->type
;
1674 if (ot
->type
== MONO_TYPE_VAR
|| ot
->type
== MONO_TYPE_MVAR
)
1677 if (klass
->valuetype
)
1678 return klass
== klassc
;
1679 return klass
->valuetype
== klassc
->valuetype
;
1682 return mono_class_is_assignable_from (klass
, klassc
);
1685 ICALL_EXPORT guint32
1686 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionTypeHandle ref_type
, MonoObjectHandle obj
, MonoError
*error
)
1689 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
1690 MonoClass
*klass
= mono_class_from_mono_type (type
);
1691 mono_class_init_checked (klass
, error
);
1692 return_val_if_nok (error
, FALSE
);
1693 MonoObjectHandle inst
= mono_object_handle_isinst (obj
, klass
, error
);
1694 return_val_if_nok (error
, FALSE
);
1695 return !MONO_HANDLE_IS_NULL (inst
);
1698 ICALL_EXPORT guint32
1699 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
1702 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
1703 MonoClass
*klass
= mono_class_from_mono_type (type
);
1704 return mono_class_get_flags (klass
);
1707 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1708 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h
, MonoError
*error
)
1711 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (field_h
);
1712 MonoClassField
*field
= MONO_HANDLE_GETVAL (field_h
, field
);
1713 MonoClass
*klass
= field
->parent
;
1715 MonoGenericClass
*gklass
= mono_class_try_get_generic_class (klass
);
1716 if (mono_class_is_gtd (klass
) ||
1717 (gklass
&& gklass
->context
.class_inst
->is_open
))
1718 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, NULL_HANDLE
);
1720 MonoType
*ftype
= mono_field_get_type (field
);
1721 if (ftype
&& !(ftype
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL
))
1722 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, NULL_HANDLE
);
1724 MonoMarshalType
*info
= mono_marshal_load_type_info (klass
);
1726 for (int i
= 0; i
< info
->num_fields
; ++i
) {
1727 if (info
->fields
[i
].field
== field
) {
1728 if (!info
->fields
[i
].mspec
)
1729 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, NULL_HANDLE
);
1731 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain
, klass
, info
->fields
[i
].mspec
, error
);
1736 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute
, NULL_HANDLE
);
1739 ICALL_EXPORT MonoReflectionFieldHandle
1740 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
*handle
, MonoType
*type
, MonoError
*error
)
1749 klass
= handle
->parent
;
1751 klass
= mono_class_from_mono_type (type
);
1753 gboolean found
= klass
== handle
->parent
|| mono_class_has_parent (klass
, handle
->parent
);
1756 /* The managed code will throw the exception */
1757 return MONO_HANDLE_CAST (MonoReflectionField
, NULL_HANDLE
);
1760 return mono_field_get_object_handle (mono_domain_get (), klass
, handle
, error
);
1763 ICALL_EXPORT MonoReflectionEventHandle
1764 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent
*handle
, MonoType
*type
, MonoError
*error
)
1773 klass
= handle
->parent
;
1775 klass
= mono_class_from_mono_type (type
);
1777 gboolean found
= klass
== handle
->parent
|| mono_class_has_parent (klass
, handle
->parent
);
1779 /* Managed code will throw an exception */
1780 return MONO_HANDLE_CAST (MonoReflectionEvent
, NULL_HANDLE
);
1783 return mono_event_get_object_handle (mono_domain_get (), klass
, handle
, error
);
1787 ICALL_EXPORT MonoReflectionPropertyHandle
1788 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty
*handle
, MonoType
*type
, MonoError
*error
)
1796 klass
= handle
->parent
;
1798 klass
= mono_class_from_mono_type (type
);
1800 gboolean found
= klass
== handle
->parent
|| mono_class_has_parent (klass
, handle
->parent
);
1802 /* Managed code will throw an exception */
1803 return MONO_HANDLE_CAST (MonoReflectionProperty
, NULL_HANDLE
);
1806 return mono_property_get_object_handle (mono_domain_get (), klass
, handle
, error
);
1809 ICALL_EXPORT MonoArrayHandle
1810 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h
, MonoBoolean optional
, MonoError
*error
)
1813 MonoClassField
*field
= MONO_HANDLE_GETVAL (field_h
, field
);
1815 MonoType
*type
= mono_field_get_type_checked (field
, error
);
1817 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
1819 return type_array_from_modifiers (field
->parent
->image
, type
, optional
, error
);
1823 vell_icall_get_method_attributes (MonoMethod
*method
)
1825 return method
->flags
;
1829 ves_icall_get_method_info (MonoMethod
*method
, MonoMethodInfo
*info
, MonoError
*error
)
1831 MonoDomain
*domain
= mono_domain_get ();
1833 MonoMethodSignature
* sig
= mono_method_signature_checked (method
, error
);
1834 return_if_nok (error
);
1836 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &method
->klass
->byval_arg
, error
);
1837 return_if_nok (error
);
1839 MONO_STRUCT_SETREF (info
, parent
, MONO_HANDLE_RAW (rt
));
1841 MONO_HANDLE_ASSIGN (rt
, mono_type_get_object_handle (domain
, sig
->ret
, error
));
1842 return_if_nok (error
);
1844 MONO_STRUCT_SETREF (info
, ret
, MONO_HANDLE_RAW (rt
));
1846 info
->attrs
= method
->flags
;
1847 info
->implattrs
= method
->iflags
;
1849 if (sig
->call_convention
== MONO_CALL_DEFAULT
)
1850 callconv
= sig
->sentinelpos
>= 0 ? 2 : 1;
1852 if (sig
->call_convention
== MONO_CALL_VARARG
|| sig
->sentinelpos
>= 0)
1857 callconv
|= (sig
->hasthis
<< 5) | (sig
->explicit_this
<< 6);
1858 info
->callconv
= callconv
;
1861 ICALL_EXPORT MonoArrayHandle
1862 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod
*method
, MonoReflectionMethodHandle member
, MonoError
*error
)
1865 MonoDomain
*domain
= mono_domain_get ();
1867 MonoReflectionTypeHandle reftype
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
1868 MONO_HANDLE_GET (reftype
, member
, reftype
);
1869 MonoClass
*klass
= NULL
;
1870 if (!MONO_HANDLE_IS_NULL (reftype
))
1871 klass
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype
, type
));
1872 return mono_param_get_objects_internal (domain
, method
, klass
, error
);
1875 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1876 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod
*method
, MonoError
*error
)
1879 MonoDomain
*domain
= mono_domain_get ();
1880 MonoReflectionMarshalAsAttributeHandle res
= MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute
, NULL
);
1882 MonoMarshalSpec
**mspecs
= g_new (MonoMarshalSpec
*, mono_method_signature (method
)->param_count
+ 1);
1883 mono_method_get_marshal_info (method
, mspecs
);
1886 MONO_HANDLE_ASSIGN (res
, mono_reflection_marshal_as_attribute_from_marshal_spec (domain
, method
->klass
, mspecs
[0], error
));
1892 for (int i
= mono_method_signature (method
)->param_count
; i
>= 0; i
--)
1894 mono_metadata_free_marshal_spec (mspecs
[i
]);
1901 ves_icall_MonoField_GetFieldOffset (MonoReflectionField
*field
)
1903 MonoClass
*parent
= field
->field
->parent
;
1904 mono_class_setup_fields (parent
);
1906 return field
->field
->offset
- sizeof (MonoObject
);
1909 ICALL_EXPORT MonoReflectionTypeHandle
1910 ves_icall_MonoField_GetParentType (MonoReflectionFieldHandle field
, MonoBoolean declaring
, MonoError
*error
)
1913 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (field
);
1917 MonoClassField
*f
= MONO_HANDLE_GETVAL (field
, field
);
1920 parent
= MONO_HANDLE_GETVAL (field
, klass
);
1923 return mono_type_get_object_handle (domain
, &parent
->byval_arg
, error
);
1926 ICALL_EXPORT MonoObject
*
1927 ves_icall_MonoField_GetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
)
1930 MonoClass
*fklass
= field
->klass
;
1931 MonoClassField
*cf
= field
->field
;
1932 MonoDomain
*domain
= mono_object_domain (field
);
1934 if (fklass
->image
->assembly
->ref_only
) {
1935 mono_set_pending_exception (mono_get_exception_invalid_operation (
1936 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1940 if (mono_security_core_clr_enabled () &&
1941 !mono_security_core_clr_ensure_reflection_access_field (cf
, &error
)) {
1942 mono_error_set_pending_exception (&error
);
1946 MonoObject
* result
= mono_field_get_value_object_checked (domain
, cf
, obj
, &error
);
1947 mono_error_set_pending_exception (&error
);
1952 ves_icall_MonoField_SetValueInternal (MonoReflectionFieldHandle field
, MonoObjectHandle obj
, MonoObjectHandle value
, MonoError
*error
)
1954 MonoClassField
*cf
= MONO_HANDLE_GETVAL (field
, field
);
1956 MonoClass
*field_klass
= MONO_HANDLE_GETVAL (field
, klass
);
1957 if (field_klass
->image
->assembly
->ref_only
) {
1958 mono_error_set_invalid_operation (error
, "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods.");
1962 if (mono_security_core_clr_enabled () &&
1963 !mono_security_core_clr_ensure_reflection_access_field (cf
, error
)) {
1967 MonoType
*type
= mono_field_get_type_checked (cf
, error
);
1968 return_if_nok (error
);
1970 gboolean isref
= FALSE
;
1971 uint32_t value_gchandle
= 0;
1974 switch (type
->type
) {
1977 case MONO_TYPE_BOOLEAN
:
1980 case MONO_TYPE_CHAR
:
1989 case MONO_TYPE_VALUETYPE
:
1992 if (!MONO_HANDLE_IS_NULL (value
))
1993 v
= mono_object_handle_pin_unbox (value
, &value_gchandle
);
1995 case MONO_TYPE_STRING
:
1996 case MONO_TYPE_OBJECT
:
1997 case MONO_TYPE_CLASS
:
1998 case MONO_TYPE_ARRAY
:
1999 case MONO_TYPE_SZARRAY
:
2003 case MONO_TYPE_GENERICINST
: {
2004 MonoGenericClass
*gclass
= type
->data
.generic_class
;
2005 g_assert (!gclass
->context
.class_inst
->is_open
);
2007 if (mono_class_is_nullable (mono_class_from_mono_type (type
))) {
2008 MonoClass
*nklass
= mono_class_from_mono_type (type
);
2011 * Convert the boxed vtype into a Nullable structure.
2012 * This is complicated by the fact that Nullables have
2013 * a variable structure.
2015 MonoObjectHandle nullable
= MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (mono_domain_get (), nklass
, error
));
2016 return_if_nok (error
);
2018 uint32_t nullable_gchandle
= 0;
2019 guint8
*nval
= mono_object_handle_pin_unbox (nullable
, &nullable_gchandle
);
2020 mono_nullable_init_from_handle (nval
, value
, nklass
);
2023 value_gchandle
= nullable_gchandle
;
2027 isref
= !gclass
->container_class
->valuetype
;
2028 if (!isref
&& !MONO_HANDLE_IS_NULL (value
)) {
2029 v
= mono_object_handle_pin_unbox (value
, &value_gchandle
);
2035 g_error ("type 0x%x not handled in "
2036 "ves_icall_FieldInfo_SetValueInternal", type
->type
);
2041 /* either value is a reference type, or it's a value type and we pinned
2042 * it and v points to the payload. */
2043 g_assert ((isref
&& v
== NULL
&& value_gchandle
== 0) ||
2044 (!isref
&& v
!= NULL
&& value_gchandle
!= 0) ||
2045 (!isref
&& v
== NULL
&& value_gchandle
== 0));
2047 if (type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
2048 MonoVTable
*vtable
= mono_class_vtable_full (MONO_HANDLE_DOMAIN (field
), cf
->parent
, error
);
2052 if (!vtable
->initialized
) {
2053 if (!mono_runtime_class_init_full (vtable
, error
))
2057 mono_field_static_set_value (vtable
, cf
, MONO_HANDLE_RAW (value
)); /* FIXME make mono_field_static_set_value work with handles for value */
2059 mono_field_static_set_value (vtable
, cf
, v
);
2063 MONO_HANDLE_SET_FIELD_REF (obj
, cf
, value
);
2065 mono_field_set_value (MONO_HANDLE_RAW (obj
), cf
, v
); /* FIXME: make mono_field_set_value take a handle for obj */
2069 mono_gchandle_free (value_gchandle
);
2073 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField
*field
, MonoReflectionType
*field_type
, MonoTypedRef
*obj
, MonoObject
*value
, MonoReflectionType
*context_type
)
2082 if (!MONO_TYPE_ISSTRUCT (&f
->parent
->byval_arg
)) {
2083 mono_set_pending_exception (mono_get_exception_not_implemented (NULL
));
2087 if (MONO_TYPE_IS_REFERENCE (f
->type
))
2088 mono_copy_value (f
->type
, (guint8
*)obj
->value
+ f
->offset
- sizeof (MonoObject
), value
, FALSE
);
2090 mono_copy_value (f
->type
, (guint8
*)obj
->value
+ f
->offset
- sizeof (MonoObject
), mono_object_unbox (value
), FALSE
);
2093 ICALL_EXPORT MonoObject
*
2094 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField
*rfield
)
2096 MonoObject
*o
= NULL
;
2097 MonoClassField
*field
= rfield
->field
;
2099 MonoDomain
*domain
= mono_object_domain (rfield
);
2101 MonoTypeEnum def_type
;
2102 const char *def_value
;
2106 mono_class_init (field
->parent
);
2108 t
= mono_field_get_type_checked (field
, &error
);
2109 if (!mono_error_ok (&error
)) {
2110 mono_error_set_pending_exception (&error
);
2114 if (!(t
->attrs
& FIELD_ATTRIBUTE_HAS_DEFAULT
)) {
2115 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL
));
2119 if (image_is_dynamic (field
->parent
->image
)) {
2120 MonoClass
*klass
= field
->parent
;
2121 int fidx
= field
- klass
->fields
;
2122 MonoFieldDefaultValue
*def_values
= mono_class_get_field_def_values (klass
);
2124 g_assert (def_values
);
2125 def_type
= def_values
[fidx
].def_type
;
2126 def_value
= def_values
[fidx
].data
;
2128 if (def_type
== MONO_TYPE_END
) {
2129 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL
));
2133 def_value
= mono_class_get_field_default_value (field
, &def_type
);
2134 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2136 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL
));
2141 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2145 case MONO_TYPE_BOOLEAN
:
2148 case MONO_TYPE_CHAR
:
2156 case MONO_TYPE_R8
: {
2159 /* boxed value type */
2160 t
= g_new0 (MonoType
, 1);
2162 klass
= mono_class_from_mono_type (t
);
2164 o
= mono_object_new_checked (domain
, klass
, &error
);
2165 if (!mono_error_ok (&error
)) {
2166 mono_error_set_pending_exception (&error
);
2169 v
= ((gchar
*) o
) + sizeof (MonoObject
);
2170 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, v
, &error
);
2171 if (mono_error_set_pending_exception (&error
))
2175 case MONO_TYPE_STRING
:
2176 case MONO_TYPE_CLASS
:
2177 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, &o
, &error
);
2178 if (mono_error_set_pending_exception (&error
))
2182 g_assert_not_reached ();
2188 ICALL_EXPORT MonoReflectionTypeHandle
2189 ves_icall_MonoField_ResolveType (MonoReflectionFieldHandle ref_field
, MonoError
*error
)
2192 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_field
);
2193 MonoClassField
*field
= MONO_HANDLE_GETVAL (ref_field
, field
);
2194 MonoType
*type
= mono_field_get_type_checked (field
, error
);
2195 if (!is_ok (error
)) {
2196 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2198 return mono_type_get_object_handle (domain
, type
, error
);
2201 /* From MonoProperty.cs */
2203 PInfo_Attributes
= 1,
2204 PInfo_GetMethod
= 1 << 1,
2205 PInfo_SetMethod
= 1 << 2,
2206 PInfo_ReflectedType
= 1 << 3,
2207 PInfo_DeclaringType
= 1 << 4,
2212 ves_icall_MonoPropertyInfo_get_property_info (MonoReflectionPropertyHandle property
, MonoPropertyInfo
*info
, PInfo req_info
, MonoError
*error
)
2215 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (property
);
2216 const MonoProperty
*pproperty
= MONO_HANDLE_GETVAL (property
, property
);
2218 if ((req_info
& PInfo_ReflectedType
) != 0) {
2219 MonoClass
*klass
= MONO_HANDLE_GETVAL (property
, klass
);
2220 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
2221 return_if_nok (error
);
2223 MONO_STRUCT_SETREF (info
, parent
, MONO_HANDLE_RAW (rt
));
2225 if ((req_info
& PInfo_DeclaringType
) != 0) {
2226 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &pproperty
->parent
->byval_arg
, error
);
2227 return_if_nok (error
);
2229 MONO_STRUCT_SETREF (info
, declaring_type
, MONO_HANDLE_RAW (rt
));
2232 if ((req_info
& PInfo_Name
) != 0) {
2233 MonoStringHandle name
= mono_string_new_handle (domain
, pproperty
->name
, error
);
2234 return_if_nok (error
);
2236 MONO_STRUCT_SETREF (info
, name
, MONO_HANDLE_RAW (name
));
2239 if ((req_info
& PInfo_Attributes
) != 0)
2240 info
->attrs
= pproperty
->attrs
;
2242 if ((req_info
& PInfo_GetMethod
) != 0) {
2243 MonoClass
*property_klass
= MONO_HANDLE_GETVAL (property
, klass
);
2244 MonoReflectionMethodHandle rm
;
2245 if (pproperty
->get
&&
2246 (((pproperty
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) ||
2247 pproperty
->get
->klass
== property_klass
)) {
2248 rm
= mono_method_get_object_handle (domain
, pproperty
->get
, property_klass
, error
);
2249 return_if_nok (error
);
2251 rm
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2254 MONO_STRUCT_SETREF (info
, get
, MONO_HANDLE_RAW (rm
));
2256 if ((req_info
& PInfo_SetMethod
) != 0) {
2257 MonoClass
*property_klass
= MONO_HANDLE_GETVAL (property
, klass
);
2258 MonoReflectionMethodHandle rm
;
2259 if (pproperty
->set
&&
2260 (((pproperty
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) ||
2261 pproperty
->set
->klass
== property_klass
)) {
2262 rm
= mono_method_get_object_handle (domain
, pproperty
->set
, property_klass
, error
);
2263 return_if_nok (error
);
2265 rm
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2268 MONO_STRUCT_SETREF (info
, set
, MONO_HANDLE_RAW (rm
));
2271 * There may be other methods defined for properties, though, it seems they are not exposed
2272 * in the reflection API
2277 add_event_other_methods_to_array (MonoDomain
*domain
, MonoMethod
*m
, MonoArrayHandle dest
, int i
, MonoError
*error
)
2279 HANDLE_FUNCTION_ENTER ();
2281 MonoReflectionMethodHandle rm
= mono_method_get_object_handle (domain
, m
, NULL
, error
);
2284 MONO_HANDLE_ARRAY_SETREF (dest
, i
, rm
);
2286 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2290 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEventHandle ref_event
, MonoEventInfo
*info
, MonoError
*error
)
2293 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_event
);
2295 MonoClass
*klass
= MONO_HANDLE_GETVAL (ref_event
, klass
);
2296 MonoEvent
*event
= MONO_HANDLE_GETVAL (ref_event
, event
);
2298 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
2299 return_if_nok (error
);
2300 MONO_STRUCT_SETREF (info
, reflected_type
, MONO_HANDLE_RAW (rt
));
2302 rt
= mono_type_get_object_handle (domain
, &event
->parent
->byval_arg
, error
);
2303 return_if_nok (error
);
2304 MONO_STRUCT_SETREF (info
, declaring_type
, MONO_HANDLE_RAW (rt
));
2306 MonoStringHandle ev_name
= mono_string_new_handle (domain
, event
->name
, error
);
2307 return_if_nok (error
);
2308 MONO_STRUCT_SETREF (info
, name
, MONO_HANDLE_RAW (ev_name
));
2310 info
->attrs
= event
->attrs
;
2312 MonoReflectionMethodHandle rm
;
2314 rm
= mono_method_get_object_handle (domain
, event
->add
, NULL
, error
);
2315 return_if_nok (error
);
2317 rm
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2320 MONO_STRUCT_SETREF (info
, add_method
, MONO_HANDLE_RAW (rm
));
2322 if (event
->remove
) {
2323 rm
= mono_method_get_object_handle (domain
, event
->remove
, NULL
, error
);
2324 return_if_nok (error
);
2326 rm
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2329 MONO_STRUCT_SETREF (info
, remove_method
, MONO_HANDLE_RAW (rm
));
2332 rm
= mono_method_get_object_handle (domain
, event
->raise
, NULL
, error
);
2333 return_if_nok (error
);
2335 rm
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2338 MONO_STRUCT_SETREF (info
, raise_method
, MONO_HANDLE_RAW (rm
));
2340 #ifndef MONO_SMALL_CONFIG
2343 while (event
->other
[n
])
2345 MonoArrayHandle info_arr
= mono_array_new_handle (domain
, mono_defaults
.method_info_class
, n
, error
);
2346 return_if_nok (error
);
2348 MONO_STRUCT_SETREF (info
, other_methods
, MONO_HANDLE_RAW (info_arr
));
2350 for (i
= 0; i
< n
; i
++)
2351 if (!add_event_other_methods_to_array (domain
, event
->other
[i
], info_arr
, i
, error
))
2358 collect_interfaces (MonoClass
*klass
, GHashTable
*ifaces
, MonoError
*error
)
2363 mono_class_setup_interfaces (klass
, error
);
2364 if (!mono_error_ok (error
))
2367 for (i
= 0; i
< klass
->interface_count
; i
++) {
2368 ic
= klass
->interfaces
[i
];
2369 g_hash_table_insert (ifaces
, ic
, ic
);
2371 collect_interfaces (ic
, ifaces
, error
);
2372 if (!mono_error_ok (error
))
2378 MonoArrayHandle iface_array
;
2379 MonoGenericContext
*context
;
2383 } FillIfaceArrayData
;
2386 fill_iface_array (gpointer key
, gpointer value
, gpointer user_data
)
2388 HANDLE_FUNCTION_ENTER ();
2389 FillIfaceArrayData
*data
= (FillIfaceArrayData
*)user_data
;
2390 MonoClass
*ic
= (MonoClass
*)key
;
2391 MonoType
*ret
= &ic
->byval_arg
, *inflated
= NULL
;
2392 MonoError
*error
= data
->error
;
2397 if (data
->context
&& mono_class_is_ginst (ic
) && mono_class_get_generic_class (ic
)->context
.class_inst
->is_open
) {
2398 inflated
= ret
= mono_class_inflate_generic_type_checked (ret
, data
->context
, error
);
2403 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (data
->domain
, ret
, error
);
2407 MONO_HANDLE_ARRAY_SETREF (data
->iface_array
, data
->next_idx
, rt
);
2411 mono_metadata_free_type (inflated
);
2413 HANDLE_FUNCTION_RETURN ();
2417 get_interfaces_hash (gconstpointer v1
)
2419 MonoClass
*k
= (MonoClass
*)v1
;
2421 return k
->type_token
;
2424 ICALL_EXPORT MonoArrayHandle
2425 ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2428 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2429 MonoClass
*klass
= mono_class_from_mono_type (type
);
2431 GHashTable
*iface_hash
= g_hash_table_new (get_interfaces_hash
, NULL
);
2433 MonoGenericContext
*context
= NULL
;
2434 if (mono_class_is_ginst (klass
) && mono_class_get_generic_class (klass
)->context
.class_inst
->is_open
) {
2435 context
= mono_class_get_context (klass
);
2436 klass
= mono_class_get_generic_class (klass
)->container_class
;
2439 for (MonoClass
*parent
= klass
; parent
; parent
= parent
->parent
) {
2440 mono_class_setup_interfaces (parent
, error
);
2443 collect_interfaces (parent
, iface_hash
, error
);
2448 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2450 int len
= g_hash_table_size (iface_hash
);
2452 g_hash_table_destroy (iface_hash
);
2453 if (!domain
->empty_types
) {
2454 domain
->empty_types
= mono_array_new_cached (domain
, mono_defaults
.runtimetype_class
, 0, error
);
2458 return MONO_HANDLE_NEW (MonoArray
, domain
->empty_types
);
2461 FillIfaceArrayData data
;
2462 data
.iface_array
= MONO_HANDLE_NEW (MonoArray
, mono_array_new_cached (domain
, mono_defaults
.runtimetype_class
, len
, error
));
2465 data
.context
= context
;
2467 data
.domain
= domain
;
2470 g_hash_table_foreach (iface_hash
, fill_iface_array
, &data
);
2475 g_hash_table_destroy (iface_hash
);
2476 return data
.iface_array
;
2479 g_hash_table_destroy (iface_hash
);
2480 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
2484 set_interface_map_data_method_object (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*iclass
, int ioffset
, MonoClass
*klass
, MonoArrayHandle targets
, MonoArrayHandle methods
, int i
, MonoError
*error
)
2486 HANDLE_FUNCTION_ENTER ();
2488 MonoReflectionMethodHandle member
= mono_method_get_object_handle (domain
, method
, iclass
, error
);
2492 MONO_HANDLE_ARRAY_SETREF (methods
, i
, member
);
2494 MONO_HANDLE_ASSIGN (member
, mono_method_get_object_handle (domain
, klass
->vtable
[i
+ ioffset
], klass
, error
));
2498 MONO_HANDLE_ARRAY_SETREF (targets
, i
, member
);
2501 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2505 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionTypeHandle ref_type
, MonoReflectionTypeHandle ref_iface
, MonoArrayHandleOut targets
, MonoArrayHandleOut methods
, MonoError
*error
)
2508 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2509 MonoClass
*klass
= mono_class_from_mono_type (type
);
2510 MonoType
*iface
= MONO_HANDLE_GETVAL (ref_iface
, type
);
2511 MonoClass
*iclass
= mono_class_from_mono_type (iface
);
2513 mono_class_init_checked (klass
, error
);
2514 return_if_nok (error
);
2515 mono_class_init_checked (iclass
, error
);
2516 return_if_nok (error
);
2518 mono_class_setup_vtable (klass
);
2520 gboolean variance_used
;
2521 int ioffset
= mono_class_interface_offset_with_variance (klass
, iclass
, &variance_used
);
2525 int len
= mono_class_num_methods (iclass
);
2526 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2527 MonoArrayHandle targets_arr
= mono_array_new_handle (domain
, mono_defaults
.method_info_class
, len
, error
);
2528 return_if_nok (error
);
2529 MONO_HANDLE_ASSIGN (targets
, targets_arr
);
2531 MonoArrayHandle methods_arr
= mono_array_new_handle (domain
, mono_defaults
.method_info_class
, len
, error
);
2532 return_if_nok (error
);
2533 MONO_HANDLE_ASSIGN (methods
, methods_arr
);
2537 gpointer iter
= NULL
;
2538 while ((method
= mono_class_get_methods (iclass
, &iter
))) {
2539 if (!set_interface_map_data_method_object (domain
, method
, iclass
, ioffset
, klass
, targets
, methods
, i
, error
))
2546 ves_icall_RuntimeType_GetPacking (MonoReflectionTypeHandle ref_type
, guint32
*packing
, guint32
*size
, MonoError
*error
)
2549 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2550 MonoClass
*klass
= mono_class_from_mono_type (type
);
2552 mono_class_init_checked (klass
, error
);
2556 if (image_is_dynamic (klass
->image
)) {
2557 MonoReflectionTypeBuilderHandle tb
= MONO_HANDLE_CAST (MonoReflectionTypeBuilder
, ref_type
);
2558 *packing
= MONO_HANDLE_GETVAL (tb
, packing_size
);
2559 *size
= MONO_HANDLE_GETVAL (tb
, class_size
);
2561 mono_metadata_packing_from_typedef (klass
->image
, klass
->type_token
, packing
, size
);
2565 ICALL_EXPORT MonoReflectionTypeHandle
2566 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2570 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2571 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2573 if (!type
->byref
&& type
->type
== MONO_TYPE_SZARRAY
) {
2574 return mono_type_get_object_handle (domain
, &type
->data
.klass
->byval_arg
, error
);
2577 MonoClass
*klass
= mono_class_from_mono_type (type
);
2578 mono_class_init_checked (klass
, error
);
2580 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2582 // GetElementType should only return a type for:
2583 // Array Pointer PassedByRef
2585 return mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
2586 else if (klass
->element_class
&& MONO_CLASS_IS_ARRAY (klass
))
2587 return mono_type_get_object_handle (domain
, &klass
->element_class
->byval_arg
, error
);
2588 else if (klass
->element_class
&& type
->type
== MONO_TYPE_PTR
)
2589 return mono_type_get_object_handle (domain
, &klass
->element_class
->byval_arg
, error
);
2591 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2594 ICALL_EXPORT MonoReflectionTypeHandle
2595 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2599 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2600 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2603 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2605 MonoClass
*klass
= mono_class_from_mono_type (type
);
2607 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2609 return mono_type_get_object_handle (domain
, &klass
->parent
->byval_arg
, error
);
2612 ICALL_EXPORT MonoBoolean
2613 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2616 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2617 return type
->type
== MONO_TYPE_PTR
;
2620 ICALL_EXPORT MonoBoolean
2621 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2624 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2625 return (!type
->byref
&& (((type
->type
>= MONO_TYPE_BOOLEAN
) && (type
->type
<= MONO_TYPE_R8
)) || (type
->type
== MONO_TYPE_I
) || (type
->type
== MONO_TYPE_U
)));
2628 ICALL_EXPORT MonoBoolean
2629 ves_icall_RuntimeTypeHandle_HasReferences (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2632 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2635 klass
= mono_class_from_mono_type (type
);
2636 mono_class_init (klass
);
2637 return klass
->has_references
;
2640 ICALL_EXPORT MonoBoolean
2641 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2644 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2648 ICALL_EXPORT MonoBoolean
2649 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2652 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2653 MonoClass
*klass
= mono_class_from_mono_type (type
);
2654 mono_class_init_checked (klass
, error
);
2658 return mono_class_is_com_object (klass
);
2661 ICALL_EXPORT guint32
2662 ves_icall_reflection_get_token (MonoObjectHandle obj
, MonoError
*error
)
2665 return mono_reflection_get_token_checked (obj
, error
);
2668 ICALL_EXPORT MonoReflectionModuleHandle
2669 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type
, MonoError
*error
)
2672 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (type
);
2673 MonoType
*t
= MONO_HANDLE_GETVAL (type
, type
);
2674 MonoClass
*klass
= mono_class_from_mono_type (t
);
2675 return mono_module_get_object_handle (domain
, klass
->image
, error
);
2678 ICALL_EXPORT MonoReflectionAssemblyHandle
2679 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type
, MonoError
*error
)
2682 MonoDomain
*domain
= mono_domain_get ();
2683 MonoType
*t
= MONO_HANDLE_GETVAL (type
, type
);
2684 MonoClass
*klass
= mono_class_from_mono_type (t
);
2685 return mono_assembly_get_object_handle (domain
, klass
->image
->assembly
, error
);
2688 ICALL_EXPORT MonoReflectionTypeHandle
2689 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2692 MonoDomain
*domain
= mono_domain_get ();
2693 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2697 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2698 if (type
->type
== MONO_TYPE_VAR
) {
2699 MonoGenericContainer
*param
= mono_type_get_generic_param_owner (type
);
2700 klass
= param
? param
->owner
.klass
: NULL
;
2701 } else if (type
->type
== MONO_TYPE_MVAR
) {
2702 MonoGenericContainer
*param
= mono_type_get_generic_param_owner (type
);
2703 klass
= param
? param
->owner
.method
->klass
: NULL
;
2705 klass
= mono_class_from_mono_type (type
)->nested_in
;
2709 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2711 return mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
2714 ICALL_EXPORT MonoStringHandle
2715 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype
, MonoError
*error
)
2717 MonoDomain
*domain
= mono_domain_get ();
2718 MonoType
*type
= MONO_HANDLE_RAW(reftype
)->type
;
2719 MonoClass
*klass
= mono_class_from_mono_type (type
);
2722 char *n
= g_strdup_printf ("%s&", klass
->name
);
2723 MonoStringHandle res
= mono_string_new_handle (domain
, n
, error
);
2729 return mono_string_new_handle (domain
, klass
->name
, error
);
2733 ICALL_EXPORT MonoStringHandle
2734 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type
, MonoError
*error
)
2736 MonoDomain
*domain
= mono_domain_get ();
2737 MonoClass
*klass
= mono_class_from_mono_type_handle (type
);
2739 while (klass
->nested_in
)
2740 klass
= klass
->nested_in
;
2742 if (klass
->name_space
[0] == '\0')
2743 return NULL_HANDLE_STRING
;
2745 return mono_string_new_handle (domain
, klass
->name_space
, error
);
2749 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2752 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2754 if (type
->type
!= MONO_TYPE_ARRAY
&& type
->type
!= MONO_TYPE_SZARRAY
) {
2755 mono_error_set_argument (error
, "type", "Type must be an array type");
2759 MonoClass
*klass
= mono_class_from_mono_type (type
);
2764 static MonoArrayHandle
2765 create_type_array (MonoDomain
*domain
, MonoBoolean runtimeTypeArray
, int count
, MonoError
*error
)
2767 return mono_array_new_handle (domain
, runtimeTypeArray
? mono_defaults
.runtimetype_class
: mono_defaults
.systemtype_class
, count
, error
);
2771 set_type_object_in_array (MonoDomain
*domain
, MonoType
*type
, MonoArrayHandle dest
, int i
, MonoError
*error
)
2773 HANDLE_FUNCTION_ENTER();
2775 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, type
, error
);
2779 MONO_HANDLE_ARRAY_SETREF (dest
, i
, rt
);
2782 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
2785 ICALL_EXPORT MonoArrayHandle
2786 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionTypeHandle ref_type
, MonoBoolean runtimeTypeArray
, MonoError
*error
)
2789 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2791 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2792 MonoClass
*klass
= mono_class_from_mono_type (type
);
2794 MonoArrayHandle res
= MONO_HANDLE_NEW (MonoArray
, NULL
);
2795 if (mono_class_is_gtd (klass
)) {
2796 MonoGenericContainer
*container
= mono_class_get_generic_container (klass
);
2797 MONO_HANDLE_ASSIGN (res
, create_type_array (domain
, runtimeTypeArray
, container
->type_argc
, error
));
2800 for (int i
= 0; i
< container
->type_argc
; ++i
) {
2801 MonoClass
*pklass
= mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container
, i
));
2803 if (!set_type_object_in_array (domain
, &pklass
->byval_arg
, res
, i
, error
))
2807 } else if (mono_class_is_ginst (klass
)) {
2808 MonoGenericInst
*inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
2809 MONO_HANDLE_ASSIGN (res
, create_type_array (domain
, runtimeTypeArray
, inst
->type_argc
, error
));
2812 for (int i
= 0; i
< inst
->type_argc
; ++i
) {
2813 if (!set_type_object_in_array (domain
, inst
->type_argv
[i
], res
, i
, error
))
2822 ICALL_EXPORT gboolean
2823 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2827 if (!IS_MONOTYPE (MONO_HANDLE_RAW(ref_type
)))
2830 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2834 MonoClass
*klass
= mono_class_from_mono_type (type
);
2835 return mono_class_is_gtd (klass
);
2838 ICALL_EXPORT MonoReflectionTypeHandle
2839 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2842 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2844 MonoReflectionTypeHandle ret
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
2849 MonoClass
*klass
= mono_class_from_mono_type (type
);
2851 if (mono_class_is_gtd (klass
)) {
2852 /* check this one */
2853 MONO_HANDLE_ASSIGN (ret
, ref_type
);
2856 if (mono_class_is_ginst (klass
)) {
2857 MonoClass
*generic_class
= mono_class_get_generic_class (klass
)->container_class
;
2859 guint32 ref_info_handle
= mono_class_get_ref_info_handle (generic_class
);
2861 if (generic_class
->wastypebuilder
&& ref_info_handle
) {
2862 MonoObjectHandle tb
= mono_gchandle_get_target_handle (ref_info_handle
);
2863 g_assert (!MONO_HANDLE_IS_NULL (tb
));
2864 MONO_HANDLE_ASSIGN (ret
, tb
);
2866 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2867 MONO_HANDLE_ASSIGN (ret
, mono_type_get_object_handle (domain
, &generic_class
->byval_arg
, error
));
2874 ICALL_EXPORT MonoReflectionTypeHandle
2875 ves_icall_RuntimeType_MakeGenericType (MonoReflectionTypeHandle reftype
, MonoArrayHandle type_array
, MonoError
*error
)
2878 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (reftype
);
2880 g_assert (IS_MONOTYPE_HANDLE (reftype
));
2881 MonoType
*type
= MONO_HANDLE_GETVAL (reftype
, type
);
2882 mono_class_init_checked (mono_class_from_mono_type (type
), error
);
2884 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2886 int count
= mono_array_handle_length (type_array
);
2887 MonoType
**types
= g_new0 (MonoType
*, count
);
2889 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
2890 for (int i
= 0; i
< count
; i
++) {
2891 MONO_HANDLE_ARRAY_GETREF (t
, type_array
, i
);
2892 types
[i
] = MONO_HANDLE_GETVAL (t
, type
);
2895 MonoType
*geninst
= mono_reflection_bind_generic_parameters (reftype
, count
, types
, error
);
2898 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2901 MonoClass
*klass
= mono_class_from_mono_type (geninst
);
2903 /*we might inflate to the GTD*/
2904 if (mono_class_is_ginst (klass
) && !mono_verifier_class_is_valid_generic_instantiation (klass
)) {
2905 mono_error_set_argument (error
, "typeArguments", "Invalid generic arguments");
2906 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
2909 return mono_type_get_object_handle (domain
, geninst
, error
);
2912 ICALL_EXPORT gboolean
2913 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2918 if (!IS_MONOTYPE (MONO_HANDLE_RAW (ref_type
)))
2921 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2925 klass
= mono_class_from_mono_type (type
);
2926 return mono_class_is_ginst (klass
) || mono_class_is_gtd (klass
);
2930 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2933 if (!IS_MONOTYPE_HANDLE (ref_type
))
2935 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2937 if (is_generic_parameter (type
))
2938 return mono_type_get_generic_param_num (type
);
2942 ICALL_EXPORT MonoGenericParamInfo
*
2943 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2946 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2947 return mono_generic_param_info (type
->data
.generic_param
);
2950 ICALL_EXPORT MonoBoolean
2951 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2953 MonoType
*type
= MONO_HANDLE_GETVAL(ref_type
, type
);
2954 return is_generic_parameter (type
);
2957 ICALL_EXPORT MonoReflectionMethodHandle
2958 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionTypeHandle ref_type
,
2959 MonoReflectionMethodHandle generic
,
2963 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
2964 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2965 MonoClass
*klass
= mono_class_from_mono_type (type
);
2967 mono_class_init_checked (klass
, error
);
2969 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
2971 MonoMethod
*generic_method
= MONO_HANDLE_GETVAL (generic
, method
);
2973 MonoReflectionMethodHandle ret
= MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
2975 gpointer iter
= NULL
;
2976 while ((method
= mono_class_get_methods (klass
, &iter
))) {
2977 if (method
->token
== generic_method
->token
) {
2978 ret
= mono_method_get_object_handle (domain
, method
, klass
, error
);
2980 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
2987 ICALL_EXPORT MonoReflectionMethodHandle
2988 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
2991 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
2992 MonoReflectionMethodHandle ret
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
2994 if (type
->byref
|| (type
->type
!= MONO_TYPE_MVAR
&& type
->type
!= MONO_TYPE_VAR
)) {
2995 mono_error_set_invalid_operation (error
, "DeclaringMethod can only be used on generic arguments");
2998 if (type
->type
== MONO_TYPE_VAR
)
3001 MonoMethod
*method
= mono_type_get_generic_param_owner (type
)->owner
.method
;
3004 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
3006 MONO_HANDLE_ASSIGN (ret
, mono_method_get_object_handle (domain
, method
, method
->klass
, error
));
3011 ICALL_EXPORT MonoBoolean
3012 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (MonoError
*error
)
3015 mono_error_set_not_implemented (error
, "%s", "");
3019 ICALL_EXPORT MonoBoolean
3020 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (MonoError
*error
)
3023 mono_error_set_not_implemented (error
, "%s", "");
3028 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethodHandle ref_method
, int* flags
, MonoStringHandleOut entry_point
, MonoStringHandleOut dll_name
, MonoError
*error
)
3030 MonoDomain
*domain
= mono_domain_get ();
3031 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
3032 MonoImage
*image
= method
->klass
->image
;
3033 MonoMethodPInvoke
*piinfo
= (MonoMethodPInvoke
*)method
;
3034 MonoTableInfo
*tables
= image
->tables
;
3035 MonoTableInfo
*im
= &tables
[MONO_TABLE_IMPLMAP
];
3036 MonoTableInfo
*mr
= &tables
[MONO_TABLE_MODULEREF
];
3037 guint32 im_cols
[MONO_IMPLMAP_SIZE
];
3038 guint32 scope_token
;
3039 const char *import
= NULL
;
3040 const char *scope
= NULL
;
3044 if (image_is_dynamic (image
)) {
3045 MonoReflectionMethodAux
*method_aux
=
3046 (MonoReflectionMethodAux
*)g_hash_table_lookup (((MonoDynamicImage
*)image
)->method_aux_hash
, method
);
3048 import
= method_aux
->dllentry
;
3049 scope
= method_aux
->dll
;
3052 if (!import
|| !scope
) {
3053 mono_error_set_argument (error
, "method", "System.Refleciton.Emit method with invalid pinvoke information");
3058 if (piinfo
->implmap_idx
) {
3059 mono_metadata_decode_row (im
, piinfo
->implmap_idx
- 1, im_cols
, MONO_IMPLMAP_SIZE
);
3061 piinfo
->piflags
= im_cols
[MONO_IMPLMAP_FLAGS
];
3062 import
= mono_metadata_string_heap (image
, im_cols
[MONO_IMPLMAP_NAME
]);
3063 scope_token
= mono_metadata_decode_row_col (mr
, im_cols
[MONO_IMPLMAP_SCOPE
] - 1, MONO_MODULEREF_NAME
);
3064 scope
= mono_metadata_string_heap (image
, scope_token
);
3068 *flags
= piinfo
->piflags
;
3069 MONO_HANDLE_ASSIGN (entry_point
, mono_string_new_handle (domain
, import
, error
));
3070 return_if_nok (error
);
3071 MONO_HANDLE_ASSIGN (dll_name
, mono_string_new_handle (domain
, scope
, error
));
3074 ICALL_EXPORT MonoReflectionMethodHandle
3075 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethodHandle ref_method
, MonoError
*error
)
3078 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
3080 if (method
->is_generic
)
3083 if (!method
->is_inflated
)
3084 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
3086 MonoMethodInflated
*imethod
= (MonoMethodInflated
*) method
;
3088 MonoMethod
*result
= imethod
->declaring
;
3089 /* Not a generic method. */
3090 if (!result
->is_generic
)
3091 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
3093 if (image_is_dynamic (method
->klass
->image
)) {
3094 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->klass
->image
;
3097 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3098 * the dynamic case as well ?
3100 mono_image_lock ((MonoImage
*)image
);
3101 MonoReflectionMethodHandle res
= MONO_HANDLE_NEW (MonoReflectionMethod
, mono_g_hash_table_lookup (image
->generic_def_objects
, imethod
));
3102 mono_image_unlock ((MonoImage
*)image
);
3104 if (!MONO_HANDLE_IS_NULL (res
))
3108 if (imethod
->context
.class_inst
) {
3109 MonoClass
*klass
= ((MonoMethod
*) imethod
)->klass
;
3110 /*Generic methods gets the context of the GTD.*/
3111 if (mono_class_get_context (klass
)) {
3112 result
= mono_class_inflate_generic_method_full_checked (result
, klass
, mono_class_get_context (klass
), error
);
3113 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
));
3117 return mono_method_get_object_handle (MONO_HANDLE_DOMAIN (ref_method
), result
, NULL
, error
);
3120 ICALL_EXPORT gboolean
3121 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethodHandle ref_method
, MonoError
*erro
)
3123 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
3124 return mono_method_signature (method
)->generic_param_count
!= 0;
3127 ICALL_EXPORT gboolean
3128 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethodHandle ref_method
, MonoError
*Error
)
3130 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
3131 return method
->is_generic
;
3135 set_array_generic_argument_handle_inflated (MonoDomain
*domain
, MonoGenericInst
*inst
, int i
, MonoArrayHandle arr
, MonoError
*error
)
3137 HANDLE_FUNCTION_ENTER ();
3139 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, inst
->type_argv
[i
], error
);
3142 MONO_HANDLE_ARRAY_SETREF (arr
, i
, rt
);
3144 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
3148 set_array_generic_argument_handle_gparam (MonoDomain
*domain
, MonoGenericContainer
*container
, int i
, MonoArrayHandle arr
, MonoError
*error
)
3150 HANDLE_FUNCTION_ENTER ();
3152 MonoGenericParam
*param
= mono_generic_container_get_param (container
, i
);
3153 MonoClass
*pklass
= mono_class_from_generic_parameter_internal (param
);
3154 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &pklass
->byval_arg
, error
);
3157 MONO_HANDLE_ARRAY_SETREF (arr
, i
, rt
);
3159 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
3162 ICALL_EXPORT MonoArrayHandle
3163 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethodHandle ref_method
, MonoError
*error
)
3166 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_method
);
3167 MonoMethod
*method
= MONO_HANDLE_GETVAL (ref_method
, method
);
3169 if (method
->is_inflated
) {
3170 MonoGenericInst
*inst
= mono_method_get_context (method
)->method_inst
;
3173 int count
= inst
->type_argc
;
3174 MonoArrayHandle res
= mono_array_new_handle (domain
, mono_defaults
.systemtype_class
, count
, error
);
3175 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
3177 for (int i
= 0; i
< count
; i
++) {
3178 if (!set_array_generic_argument_handle_inflated (domain
, inst
, i
, res
, error
))
3181 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
3186 int count
= mono_method_signature (method
)->generic_param_count
;
3187 MonoArrayHandle res
= mono_array_new_handle (domain
, mono_defaults
.systemtype_class
, count
, error
);
3188 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
3190 MonoGenericContainer
*container
= mono_method_get_generic_container (method
);
3191 for (int i
= 0; i
< count
; i
++) {
3192 if (!set_array_generic_argument_handle_gparam (domain
, container
, i
, res
, error
))
3195 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
3199 ICALL_EXPORT MonoObject
*
3200 ves_icall_InternalInvoke (MonoReflectionMethod
*method
, MonoObject
*this_arg
, MonoArray
*params
, MonoException
**exc
)
3204 * Invoke from reflection is supposed to always be a virtual call (the API
3205 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3206 * greater flexibility.
3208 MonoMethod
*m
= method
->method
;
3209 MonoMethodSignature
*sig
= mono_method_signature (m
);
3212 void *obj
= this_arg
;
3216 if (mono_security_core_clr_enabled () &&
3217 !mono_security_core_clr_ensure_reflection_access_method (m
, &error
)) {
3218 mono_error_set_pending_exception (&error
);
3222 if (!(m
->flags
& METHOD_ATTRIBUTE_STATIC
)) {
3223 if (!mono_class_vtable_full (mono_object_domain (method
), m
->klass
, &error
)) {
3224 mono_error_cleanup (&error
); /* FIXME does this make sense? */
3225 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_class_get_exception_for_failure (m
->klass
));
3230 if (!mono_object_isinst_checked (this_arg
, m
->klass
, &error
)) {
3231 if (!is_ok (&error
)) {
3232 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_error_convert_to_exception (&error
));
3235 char *this_name
= mono_type_get_full_name (mono_object_get_class (this_arg
));
3236 char *target_name
= mono_type_get_full_name (m
->klass
);
3237 char *msg
= g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name
, target_name
);
3238 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", msg
));
3240 g_free (target_name
);
3244 m
= mono_object_get_virtual_method (this_arg
, m
);
3245 /* must pass the pointer to the value for valuetype methods */
3246 if (m
->klass
->valuetype
)
3247 obj
= mono_object_unbox (this_arg
);
3248 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
3249 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target."));
3254 if (sig
->ret
->byref
) {
3255 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"));
3259 pcount
= params
? mono_array_length (params
): 0;
3260 if (pcount
!= sig
->param_count
) {
3261 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException"));
3265 if (mono_class_is_abstract (m
->klass
) && !strcmp (m
->name
, ".ctor") && !this_arg
) {
3266 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."));
3270 image
= m
->klass
->image
;
3271 if (image
->assembly
->ref_only
) {
3272 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."));
3276 if (image_is_dynamic (image
) && !((MonoDynamicImage
*)image
)->run
) {
3277 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3281 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
3285 intptr_t *lower_bounds
;
3286 pcount
= mono_array_length (params
);
3287 lengths
= (uintptr_t *)alloca (sizeof (uintptr_t) * pcount
);
3288 /* Note: the synthetized array .ctors have int32 as argument type */
3289 for (i
= 0; i
< pcount
; ++i
)
3290 lengths
[i
] = *(int32_t*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
3292 if (m
->klass
->rank
== 1 && sig
->param_count
== 2 && m
->klass
->element_class
->rank
) {
3293 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3294 arr
= mono_array_new_full_checked (mono_object_domain (params
), m
->klass
, lengths
, NULL
, &error
);
3295 if (!mono_error_ok (&error
)) {
3296 mono_error_set_pending_exception (&error
);
3300 for (i
= 0; i
< mono_array_length (arr
); ++i
) {
3301 MonoArray
*subarray
= mono_array_new_full_checked (mono_object_domain (params
), m
->klass
->element_class
, &lengths
[1], NULL
, &error
);
3302 if (!mono_error_ok (&error
)) {
3303 mono_error_set_pending_exception (&error
);
3306 mono_array_setref_fast (arr
, i
, subarray
);
3308 return (MonoObject
*)arr
;
3311 if (m
->klass
->rank
== pcount
) {
3312 /* Only lengths provided. */
3313 arr
= mono_array_new_full_checked (mono_object_domain (params
), m
->klass
, lengths
, NULL
, &error
);
3314 if (!mono_error_ok (&error
)) {
3315 mono_error_set_pending_exception (&error
);
3319 return (MonoObject
*)arr
;
3321 g_assert (pcount
== (m
->klass
->rank
* 2));
3322 /* The arguments are lower-bound-length pairs */
3323 lower_bounds
= (intptr_t *)g_alloca (sizeof (intptr_t) * pcount
);
3325 for (i
= 0; i
< pcount
/ 2; ++i
) {
3326 lower_bounds
[i
] = *(int32_t*) ((char*)mono_array_get (params
, gpointer
, (i
* 2)) + sizeof (MonoObject
));
3327 lengths
[i
] = *(int32_t*) ((char*)mono_array_get (params
, gpointer
, (i
* 2) + 1) + sizeof (MonoObject
));
3330 arr
= mono_array_new_full_checked (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
, &error
);
3331 if (!mono_error_ok (&error
)) {
3332 mono_error_set_pending_exception (&error
);
3336 return (MonoObject
*)arr
;
3339 MonoObject
*result
= mono_runtime_invoke_array_checked (m
, obj
, params
, &error
);
3340 mono_error_set_pending_exception (&error
);
3344 #ifndef DISABLE_REMOTING
3346 internal_execute_field_getter (MonoDomain
*domain
, MonoObject
*this_arg
, MonoArray
*params
, MonoArray
**outArgs
, MonoError
*error
)
3349 MonoArray
*out_args
;
3350 MonoClass
*k
= mono_object_class (this_arg
);
3354 /* If this is a proxy, then it must be a CBO */
3355 if (mono_class_is_transparent_proxy (k
)) {
3356 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this_arg
;
3357 this_arg
= tp
->rp
->unwrapped_server
;
3358 g_assert (this_arg
);
3359 k
= mono_object_class (this_arg
);
3362 name
= mono_array_get (params
, MonoString
*, 1);
3363 str
= mono_string_to_utf8_checked (name
, error
);
3364 return_if_nok (error
);
3367 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3370 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3372 if (field_klass
->valuetype
) {
3373 result
= mono_value_box_checked (domain
, field_klass
, (char *)this_arg
+ field
->offset
, error
);
3374 return_if_nok (error
);
3376 result
= (MonoObject
*)*((gpointer
*)((char *)this_arg
+ field
->offset
));
3378 out_args
= mono_array_new_checked (domain
, mono_defaults
.object_class
, 1, error
);
3379 return_if_nok (error
);
3380 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
3381 mono_array_setref (out_args
, 0, result
);
3388 g_assert_not_reached ();
3392 internal_execute_field_setter (MonoDomain
*domain
, MonoObject
*this_arg
, MonoArray
*params
, MonoArray
**outArgs
, MonoError
*error
)
3395 MonoArray
*out_args
;
3396 MonoClass
*k
= mono_object_class (this_arg
);
3402 /* If this is a proxy, then it must be a CBO */
3403 if (mono_class_is_transparent_proxy (k
)) {
3404 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this_arg
;
3405 this_arg
= tp
->rp
->unwrapped_server
;
3406 g_assert (this_arg
);
3407 k
= mono_object_class (this_arg
);
3410 name
= mono_array_get (params
, MonoString
*, 1);
3411 str
= mono_string_to_utf8_checked (name
, error
);
3412 return_if_nok (error
);
3415 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3418 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3419 MonoObject
*val
= (MonoObject
*)mono_array_get (params
, gpointer
, 2);
3421 if (field_klass
->valuetype
) {
3422 size
= mono_type_size (field
->type
, &align
);
3423 g_assert (size
== mono_class_value_size (field_klass
, NULL
));
3424 mono_gc_wbarrier_value_copy ((char *)this_arg
+ field
->offset
, (char*)val
+ sizeof (MonoObject
), 1, field_klass
);
3426 mono_gc_wbarrier_set_field (this_arg
, (char*)this_arg
+ field
->offset
, val
);
3429 out_args
= mono_array_new_checked (domain
, mono_defaults
.object_class
, 0, error
);
3430 return_if_nok (error
);
3431 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
3439 g_assert_not_reached ();
3442 ICALL_EXPORT MonoObject
*
3443 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this_arg
, MonoArray
*params
, MonoArray
**outArgs
)
3446 MonoDomain
*domain
= mono_object_domain (method
);
3447 MonoMethod
*m
= method
->method
;
3448 MonoMethodSignature
*sig
= mono_method_signature (m
);
3449 MonoArray
*out_args
;
3451 int i
, j
, outarg_count
= 0;
3453 if (m
->klass
== mono_defaults
.object_class
) {
3454 if (!strcmp (m
->name
, "FieldGetter")) {
3455 internal_execute_field_getter (domain
, this_arg
, params
, outArgs
, &error
);
3456 mono_error_set_pending_exception (&error
);
3458 } else if (!strcmp (m
->name
, "FieldSetter")) {
3459 internal_execute_field_setter (domain
, this_arg
, params
, outArgs
, &error
);
3460 mono_error_set_pending_exception (&error
);
3465 for (i
= 0; i
< mono_array_length (params
); i
++) {
3466 if (sig
->params
[i
]->byref
)
3470 out_args
= mono_array_new_checked (domain
, mono_defaults
.object_class
, outarg_count
, &error
);
3471 if (mono_error_set_pending_exception (&error
))
3474 /* handle constructors only for objects already allocated */
3475 if (!strcmp (method
->method
->name
, ".ctor"))
3476 g_assert (this_arg
);
3478 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3479 g_assert (!method
->method
->klass
->valuetype
);
3480 result
= mono_runtime_invoke_array_checked (method
->method
, this_arg
, params
, &error
);
3481 if (mono_error_set_pending_exception (&error
))
3484 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
3485 if (sig
->params
[i
]->byref
) {
3487 arg
= mono_array_get (params
, gpointer
, i
);
3488 mono_array_setref (out_args
, j
, arg
);
3493 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
3500 read_enum_value (const char *mem
, int type
)
3503 case MONO_TYPE_BOOLEAN
:
3505 return *(guint8
*)mem
;
3507 return *(gint8
*)mem
;
3508 case MONO_TYPE_CHAR
:
3510 return read16 (mem
);
3512 return (gint16
) read16 (mem
);
3514 return read32 (mem
);
3516 return (gint32
) read32 (mem
);
3519 return read64 (mem
);
3521 g_assert_not_reached ();
3527 write_enum_value (char *mem
, int type
, guint64 value
)
3531 case MONO_TYPE_I1
: {
3532 guint8
*p
= (guint8
*)mem
;
3538 case MONO_TYPE_CHAR
: {
3539 guint16
*p
= (guint16
*)mem
;
3544 case MONO_TYPE_I4
: {
3545 guint32
*p
= (guint32
*)mem
;
3550 case MONO_TYPE_I8
: {
3551 guint64
*p
= (guint64
*)mem
;
3556 g_assert_not_reached ();
3561 ICALL_EXPORT MonoObject
*
3562 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, guint64 value
)
3570 domain
= mono_object_domain (enumType
);
3571 enumc
= mono_class_from_mono_type (enumType
->type
);
3573 mono_class_init_checked (enumc
, &error
);
3574 if (mono_error_set_pending_exception (&error
))
3577 etype
= mono_class_enum_basetype (enumc
);
3579 res
= mono_object_new_checked (domain
, enumc
, &error
);
3580 if (mono_error_set_pending_exception (&error
))
3582 write_enum_value ((char *)res
+ sizeof (MonoObject
), etype
->type
, value
);
3587 ICALL_EXPORT MonoBoolean
3588 ves_icall_System_Enum_InternalHasFlag (MonoObject
*a
, MonoObject
*b
)
3590 int size
= mono_class_value_size (a
->vtable
->klass
, NULL
);
3591 guint64 a_val
= 0, b_val
= 0;
3593 memcpy (&a_val
, mono_object_unbox (a
), size
);
3594 memcpy (&b_val
, mono_object_unbox (b
), size
);
3596 return (a_val
& b_val
) == b_val
;
3599 ICALL_EXPORT MonoObject
*
3600 ves_icall_System_Enum_get_value (MonoObject
*eobj
)
3612 g_assert (eobj
->vtable
->klass
->enumtype
);
3614 enumc
= mono_class_from_mono_type (mono_class_enum_basetype (eobj
->vtable
->klass
));
3615 res
= mono_object_new_checked (mono_object_domain (eobj
), enumc
, &error
);
3616 if (mono_error_set_pending_exception (&error
))
3618 dst
= (char *)res
+ sizeof (MonoObject
);
3619 src
= (char *)eobj
+ sizeof (MonoObject
);
3620 size
= mono_class_value_size (enumc
, NULL
);
3622 memcpy (dst
, src
, size
);
3627 ICALL_EXPORT MonoReflectionType
*
3628 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3631 MonoReflectionType
*ret
;
3635 klass
= mono_class_from_mono_type (type
->type
);
3636 mono_class_init_checked (klass
, &error
);
3637 if (mono_error_set_pending_exception (&error
))
3640 etype
= mono_class_enum_basetype (klass
);
3642 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3646 ret
= mono_type_get_object_checked (mono_object_domain (type
), etype
, &error
);
3647 mono_error_set_pending_exception (&error
);
3653 ves_icall_System_Enum_compare_value_to (MonoObject
*eobj
, MonoObject
*other
)
3655 gpointer tdata
= (char *)eobj
+ sizeof (MonoObject
);
3656 gpointer odata
= (char *)other
+ sizeof (MonoObject
);
3657 MonoType
*basetype
= mono_class_enum_basetype (eobj
->vtable
->klass
);
3658 g_assert (basetype
);
3663 if (eobj
->vtable
->klass
!= other
->vtable
->klass
)
3666 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3667 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3668 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3671 return me > other ? 1 : -1; \
3674 switch (basetype
->type
) {
3676 COMPARE_ENUM_VALUES (guint8
);
3678 COMPARE_ENUM_VALUES (gint8
);
3679 case MONO_TYPE_CHAR
:
3681 COMPARE_ENUM_VALUES (guint16
);
3683 COMPARE_ENUM_VALUES (gint16
);
3685 COMPARE_ENUM_VALUES (guint32
);
3687 COMPARE_ENUM_VALUES (gint32
);
3689 COMPARE_ENUM_VALUES (guint64
);
3691 COMPARE_ENUM_VALUES (gint64
);
3695 #undef COMPARE_ENUM_VALUES
3696 /* indicates that the enum was of an unsupported unerlying type */
3701 ves_icall_System_Enum_get_hashcode (MonoObject
*eobj
)
3703 gpointer data
= (char *)eobj
+ sizeof (MonoObject
);
3704 MonoType
*basetype
= mono_class_enum_basetype (eobj
->vtable
->klass
);
3705 g_assert (basetype
);
3707 switch (basetype
->type
) {
3708 case MONO_TYPE_I1
: {
3709 gint8 value
= *((gint8
*)data
);
3710 return ((int)value
^ (int)value
<< 8);
3713 return *((guint8
*)data
);
3714 case MONO_TYPE_CHAR
:
3716 return *((guint16
*)data
);
3718 case MONO_TYPE_I2
: {
3719 gint16 value
= *((gint16
*)data
);
3720 return ((int)(guint16
)value
| (((int)value
) << 16));
3723 return *((guint32
*)data
);
3725 return *((gint32
*)data
);
3727 case MONO_TYPE_I8
: {
3728 gint64 value
= *((gint64
*)data
);
3729 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3732 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3738 get_enum_field (MonoDomain
*domain
, MonoArrayHandle names
, MonoArrayHandle values
, int base_type
, MonoClassField
*field
, guint
* j
, guint64
*previous_value
, gboolean
*sorted
, MonoError
*error
)
3741 HANDLE_FUNCTION_ENTER();
3742 guint64 field_value
;
3744 MonoTypeEnum def_type
;
3746 if (!(field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
))
3748 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3750 if (mono_field_is_deleted (field
))
3752 MonoStringHandle name
= mono_string_new_handle (domain
, mono_field_get_name (field
), error
);
3755 MONO_HANDLE_ARRAY_SETREF (names
, *j
, name
);
3757 p
= mono_class_get_field_default_value (field
, &def_type
);
3758 /* len = */ mono_metadata_decode_blob_size (p
, &p
);
3760 field_value
= read_enum_value (p
, base_type
);
3761 MONO_HANDLE_ARRAY_SETVAL (values
, guint64
, *j
, field_value
);
3763 if (*previous_value
> field_value
)
3766 *previous_value
= field_value
;
3769 HANDLE_FUNCTION_RETURN();
3772 ICALL_EXPORT MonoBoolean
3773 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type
, MonoArrayHandleOut values
, MonoArrayHandleOut names
, MonoError
*error
)
3775 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (type
);
3776 MonoClass
*enumc
= mono_class_from_mono_type (MONO_HANDLE_RAW(type
)->type
);
3777 guint j
= 0, nvalues
;
3779 MonoClassField
*field
;
3781 guint64 previous_value
= 0;
3782 gboolean sorted
= TRUE
;
3785 mono_class_init_checked (enumc
, error
);
3786 return_val_if_nok (error
, FALSE
);
3788 if (!enumc
->enumtype
) {
3789 mono_error_set_argument (error
, "enumType", "Type provided must be an Enum.");
3793 base_type
= mono_class_enum_basetype (enumc
)->type
;
3795 nvalues
= mono_class_num_fields (enumc
) > 0 ? mono_class_num_fields (enumc
) - 1 : 0;
3796 MONO_HANDLE_ASSIGN(names
, mono_array_new_handle (domain
, mono_defaults
.string_class
, nvalues
, error
));
3797 return_val_if_nok (error
, FALSE
);
3798 MONO_HANDLE_ASSIGN(values
, mono_array_new_handle (domain
, mono_defaults
.uint64_class
, nvalues
, error
));
3799 return_val_if_nok (error
, FALSE
);
3802 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3803 get_enum_field(domain
, names
, values
, base_type
, field
, &j
, &previous_value
, &sorted
, error
);
3807 return_val_if_nok (error
, FALSE
);
3813 BFLAGS_IgnoreCase
= 1,
3814 BFLAGS_DeclaredOnly
= 2,
3815 BFLAGS_Instance
= 4,
3817 BFLAGS_Public
= 0x10,
3818 BFLAGS_NonPublic
= 0x20,
3819 BFLAGS_FlattenHierarchy
= 0x40,
3820 BFLAGS_InvokeMethod
= 0x100,
3821 BFLAGS_CreateInstance
= 0x200,
3822 BFLAGS_GetField
= 0x400,
3823 BFLAGS_SetField
= 0x800,
3824 BFLAGS_GetProperty
= 0x1000,
3825 BFLAGS_SetProperty
= 0x2000,
3826 BFLAGS_ExactBinding
= 0x10000,
3827 BFLAGS_SuppressChangeType
= 0x20000,
3828 BFLAGS_OptionalParamBinding
= 0x40000
3831 ICALL_EXPORT GPtrArray
*
3832 ves_icall_RuntimeType_GetFields_native (MonoReflectionTypeHandle ref_type
, char *utf8_name
, guint32 bflags
, MonoError
*error
)
3835 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
3838 return g_ptr_array_new ();
3841 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3842 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? mono_utf8_strcasecmp
: strcmp
;
3844 MonoClass
*startklass
, *klass
;
3845 klass
= startklass
= mono_class_from_mono_type (type
);
3847 GPtrArray
*ptr_array
= g_ptr_array_sized_new (16);
3850 if (mono_class_has_failure (klass
)) {
3851 mono_error_set_for_class_failure (error
, klass
);
3855 MonoClassField
*field
;
3856 gpointer iter
= NULL
;
3857 while ((field
= mono_class_get_fields_lazy (klass
, &iter
))) {
3858 guint32 flags
= mono_field_get_flags (field
);
3860 if (mono_field_is_deleted_with_flags (field
, flags
))
3862 if ((flags
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3863 if (bflags
& BFLAGS_Public
)
3865 } else if ((klass
== startklass
) || (flags
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3866 if (bflags
& BFLAGS_NonPublic
) {
3873 if (flags
& FIELD_ATTRIBUTE_STATIC
) {
3874 if (bflags
& BFLAGS_Static
)
3875 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3878 if (bflags
& BFLAGS_Instance
)
3885 if (utf8_name
!= NULL
&& compare_func (mono_field_get_name (field
), utf8_name
))
3888 g_ptr_array_add (ptr_array
, field
);
3890 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3896 g_ptr_array_free (ptr_array
, TRUE
);
3901 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3903 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3904 case METHOD_ATTRIBUTE_ASSEM
:
3905 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3906 case METHOD_ATTRIBUTE_PRIVATE
:
3908 case METHOD_ATTRIBUTE_PUBLIC
:
3916 mono_class_get_methods_by_name (MonoClass
*klass
, const char *name
, guint32 bflags
, gboolean ignore_case
, gboolean allow_ctors
, MonoError
*error
)
3919 MonoClass
*startklass
;
3923 /*FIXME, use MonoBitSet*/
3924 guint32 method_slots_default
[8];
3925 guint32
*method_slots
= NULL
;
3926 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3928 array
= g_ptr_array_new ();
3933 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3935 /* An optimization for calls made from Delegate:CreateDelegate () */
3936 if (klass
->delegate
&& name
&& !strcmp (name
, "Invoke") && (bflags
== (BFLAGS_Public
| BFLAGS_Static
| BFLAGS_Instance
))) {
3937 method
= mono_get_delegate_invoke (klass
);
3940 g_ptr_array_add (array
, method
);
3944 mono_class_setup_methods (klass
);
3945 mono_class_setup_vtable (klass
);
3946 if (mono_class_has_failure (klass
))
3949 if (is_generic_parameter (&klass
->byval_arg
))
3950 nslots
= mono_class_get_vtable_size (klass
->parent
);
3952 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : mono_class_get_vtable_size (klass
);
3953 if (nslots
>= sizeof (method_slots_default
) * 8) {
3954 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3956 method_slots
= method_slots_default
;
3957 memset (method_slots
, 0, sizeof (method_slots_default
));
3960 mono_class_setup_methods (klass
);
3961 mono_class_setup_vtable (klass
);
3962 if (mono_class_has_failure (klass
))
3966 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3968 if (method
->slot
!= -1) {
3969 g_assert (method
->slot
< nslots
);
3970 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3972 if (!(method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
))
3973 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3976 if (!allow_ctors
&& method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3978 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3979 if (bflags
& BFLAGS_Public
)
3981 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3987 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3988 if (bflags
& BFLAGS_Static
)
3989 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3992 if (bflags
& BFLAGS_Instance
)
4000 if (compare_func (name
, method
->name
))
4005 g_ptr_array_add (array
, method
);
4007 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4009 if (method_slots
!= method_slots_default
)
4010 g_free (method_slots
);
4015 if (method_slots
!= method_slots_default
)
4016 g_free (method_slots
);
4017 g_ptr_array_free (array
, TRUE
);
4019 g_assert (mono_class_has_failure (klass
));
4020 mono_error_set_for_class_failure (error
, klass
);
4024 ICALL_EXPORT GPtrArray
*
4025 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionTypeHandle ref_type
, const char *mname
, guint32 bflags
, MonoBoolean ignore_case
, MonoError
*error
)
4028 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4030 MonoClass
*klass
= mono_class_from_mono_type (type
);
4032 return g_ptr_array_new ();
4035 return mono_class_get_methods_by_name (klass
, mname
, bflags
, ignore_case
, FALSE
, error
);
4038 ICALL_EXPORT GPtrArray
*
4039 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionTypeHandle ref_type
, guint32 bflags
, MonoError
*error
)
4042 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4044 return g_ptr_array_new ();
4047 MonoClass
*startklass
, *klass
;
4048 klass
= startklass
= mono_class_from_mono_type (type
);
4050 mono_class_setup_methods (klass
);
4051 if (mono_class_has_failure (klass
)) {
4052 mono_error_set_for_class_failure (error
, klass
);
4057 GPtrArray
*res_array
= g_ptr_array_sized_new (4); /* FIXME, guestimating */
4060 gpointer iter
= NULL
;
4061 while ((method
= mono_class_get_methods (klass
, &iter
))) {
4063 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
4065 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
4066 if (bflags
& BFLAGS_Public
)
4069 if (bflags
& BFLAGS_NonPublic
)
4075 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
4076 if (bflags
& BFLAGS_Static
)
4077 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
4080 if (bflags
& BFLAGS_Instance
)
4086 g_ptr_array_add (res_array
, method
);
4093 property_hash (gconstpointer data
)
4095 MonoProperty
*prop
= (MonoProperty
*)data
;
4097 return g_str_hash (prop
->name
);
4101 property_accessor_override (MonoMethod
*method1
, MonoMethod
*method2
)
4103 if (method1
->slot
!= -1 && method1
->slot
== method2
->slot
)
4106 if (mono_class_get_generic_type_definition (method1
->klass
) == mono_class_get_generic_type_definition (method2
->klass
)) {
4107 if (method1
->is_inflated
)
4108 method1
= ((MonoMethodInflated
*) method1
)->declaring
;
4109 if (method2
->is_inflated
)
4110 method2
= ((MonoMethodInflated
*) method2
)->declaring
;
4113 return mono_metadata_signature_equal (mono_method_signature (method1
), mono_method_signature (method2
));
4117 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
4119 // Properties are hide-by-name-and-signature
4120 if (!g_str_equal (prop1
->name
, prop2
->name
))
4123 /* If we see a property in a generic method, we want to
4124 compare the generic signatures, not the inflated signatures
4125 because we might conflate two properties that were
4129 public T this[T t] { getter { return t; } } // method 1
4130 public U this[U u] { getter { return u; } } // method 2
4133 If we see int Foo<int,int>::Item[int] we need to know if
4134 the indexer came from method 1 or from method 2, and we
4135 shouldn't conflate them. (Bugzilla 36283)
4137 if (prop1
->get
&& prop2
->get
&& !property_accessor_override (prop1
->get
, prop2
->get
))
4140 if (prop1
->set
&& prop2
->set
&& !property_accessor_override (prop1
->set
, prop2
->set
))
4147 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
4152 return method_nonpublic (accessor
, start_klass
);
4155 ICALL_EXPORT GPtrArray
*
4156 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionTypeHandle ref_type
, gchar
*propname
, guint32 bflags
, MonoBoolean ignore_case
, MonoError
*error
)
4159 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4163 return g_ptr_array_new ();
4167 MonoClass
*startklass
, *klass
;
4168 klass
= startklass
= mono_class_from_mono_type (type
);
4170 int (*compare_func
) (const char *s1
, const char *s2
) = (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
4172 GPtrArray
*res_array
= g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4174 GHashTable
*properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
4177 mono_class_setup_methods (klass
);
4178 mono_class_setup_vtable (klass
);
4179 if (mono_class_has_failure (klass
)) {
4180 mono_error_set_for_class_failure (error
, klass
);
4185 gpointer iter
= NULL
;
4186 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
4188 MonoMethod
*method
= prop
->get
;
4193 flags
= method
->flags
;
4194 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
4195 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
4196 if (bflags
& BFLAGS_Public
)
4198 } else if (bflags
& BFLAGS_NonPublic
) {
4199 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
4200 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
4207 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
4208 if (bflags
& BFLAGS_Static
)
4209 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
4212 if (bflags
& BFLAGS_Instance
)
4220 if (propname
!= NULL
&& compare_func (propname
, prop
->name
))
4223 if (g_hash_table_lookup (properties
, prop
))
4226 g_ptr_array_add (res_array
, prop
);
4228 g_hash_table_insert (properties
, prop
, prop
);
4230 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4233 g_hash_table_destroy (properties
);
4240 g_hash_table_destroy (properties
);
4241 g_ptr_array_free (res_array
, TRUE
);
4247 event_hash (gconstpointer data
)
4249 MonoEvent
*event
= (MonoEvent
*)data
;
4251 return g_str_hash (event
->name
);
4255 event_equal (MonoEvent
*event1
, MonoEvent
*event2
)
4257 // Events are hide-by-name
4258 return g_str_equal (event1
->name
, event2
->name
);
4261 ICALL_EXPORT GPtrArray
*
4262 ves_icall_RuntimeType_GetEvents_native (MonoReflectionTypeHandle ref_type
, char *utf8_name
, guint32 bflags
, MonoError
*error
)
4265 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4268 return g_ptr_array_new ();
4271 int (*compare_func
) (const char *s1
, const char *s2
) = (bflags
& BFLAGS_IgnoreCase
) ? mono_utf8_strcasecmp
: strcmp
;
4273 GPtrArray
*res_array
= g_ptr_array_sized_new (4);
4275 MonoClass
*startklass
, *klass
;
4276 klass
= startklass
= mono_class_from_mono_type (type
);
4278 GHashTable
*events
= g_hash_table_new (event_hash
, (GEqualFunc
)event_equal
);
4280 mono_class_setup_methods (klass
);
4281 mono_class_setup_vtable (klass
);
4282 if (mono_class_has_failure (klass
)) {
4283 mono_error_set_for_class_failure (error
, klass
);
4288 gpointer iter
= NULL
;
4289 while ((event
= mono_class_get_events (klass
, &iter
))) {
4291 MonoMethod
*method
= event
->add
;
4293 method
= event
->remove
;
4295 method
= event
->raise
;
4297 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
4298 if (bflags
& BFLAGS_Public
)
4300 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
4301 if (bflags
& BFLAGS_NonPublic
)
4306 if (bflags
& BFLAGS_NonPublic
)
4312 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
4313 if (bflags
& BFLAGS_Static
)
4314 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
4317 if (bflags
& BFLAGS_Instance
)
4322 if (bflags
& BFLAGS_Instance
)
4327 if (utf8_name
!= NULL
&& compare_func (event
->name
, utf8_name
))
4330 if (g_hash_table_lookup (events
, event
))
4333 g_ptr_array_add (res_array
, event
);
4335 g_hash_table_insert (events
, event
, event
);
4337 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4340 g_hash_table_destroy (events
);
4346 g_hash_table_destroy (events
);
4348 g_ptr_array_free (res_array
, TRUE
);
4353 ICALL_EXPORT GPtrArray
*
4354 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionTypeHandle ref_type
, char *str
, guint32 bflags
, MonoError
*error
)
4357 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
4360 return g_ptr_array_new ();
4363 MonoClass
*klass
= mono_class_from_mono_type (type
);
4366 * If a nested type is generic, return its generic type definition.
4367 * Note that this means that the return value is essentially the set
4368 * of nested types of the generic type definition of @klass.
4370 * A note in MSDN claims that a generic type definition can have
4371 * nested types that aren't generic. In any case, the container of that
4372 * nested type would be the generic type definition.
4374 if (mono_class_is_ginst (klass
))
4375 klass
= mono_class_get_generic_class (klass
)->container_class
;
4377 GPtrArray
*res_array
= g_ptr_array_new ();
4380 gpointer iter
= NULL
;
4381 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4383 if ((mono_class_get_flags (nested
) & TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4384 if (bflags
& BFLAGS_Public
)
4387 if (bflags
& BFLAGS_NonPublic
)
4393 if (str
!= NULL
&& strcmp (nested
->name
, str
))
4396 g_ptr_array_add (res_array
, &nested
->byval_arg
);
4403 get_type_from_module_builder_module (MonoArrayHandle modules
, int i
, MonoTypeNameParse
*info
, MonoBoolean ignoreCase
, gboolean
*type_resolve
, MonoError
*error
)
4405 HANDLE_FUNCTION_ENTER ();
4407 MonoType
*type
= NULL
;
4408 MonoReflectionModuleBuilderHandle mb
= MONO_HANDLE_NEW (MonoReflectionModuleBuilder
, NULL
);
4409 MONO_HANDLE_ARRAY_GETREF (mb
, modules
, i
);
4410 MonoDynamicImage
*dynamic_image
= MONO_HANDLE_GETVAL (mb
, dynamic_image
);
4411 type
= mono_reflection_get_type_checked (&dynamic_image
->image
, &dynamic_image
->image
, info
, ignoreCase
, type_resolve
, error
);
4412 HANDLE_FUNCTION_RETURN_VAL (type
);
4416 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules
, int i
, MonoTypeNameParse
*info
, MonoBoolean ignoreCase
, gboolean
*type_resolve
, MonoError
*error
)
4418 HANDLE_FUNCTION_ENTER ();
4420 MonoType
*type
= NULL
;
4421 MonoReflectionModuleHandle mod
= MONO_HANDLE_NEW (MonoReflectionModule
, NULL
);
4422 MONO_HANDLE_ARRAY_GETREF (mod
, loaded_modules
, i
);
4423 MonoImage
*image
= MONO_HANDLE_GETVAL (mod
, image
);
4424 type
= mono_reflection_get_type_checked (image
, image
, info
, ignoreCase
, type_resolve
, error
);
4425 HANDLE_FUNCTION_RETURN_VAL (type
);
4428 ICALL_EXPORT MonoReflectionTypeHandle
4429 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h
, MonoReflectionModuleHandle module
, MonoStringHandle name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
, MonoError
*error
)
4433 MonoTypeNameParse info
;
4434 gboolean type_resolve
;
4436 /* On MS.NET, this does not fire a TypeResolve event */
4437 type_resolve
= TRUE
;
4438 char *str
= mono_string_handle_to_utf8 (name
, error
);
4442 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4443 if (!mono_reflection_parse_type (str
, &info
)) {
4445 mono_reflection_free_type_info (&info
);
4447 mono_error_set_argument (error
, "name", "failed to parse the type");
4450 /*g_print ("failed parse\n");*/
4451 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4454 if (info
.assembly
.name
) {
4456 mono_reflection_free_type_info (&info
);
4458 /* 1.0 and 2.0 throw different exceptions */
4459 if (mono_defaults
.generic_ilist_class
)
4460 mono_error_set_argument (error
, NULL
, "Type names passed to Assembly.GetType() must not specify an assembly.");
4462 mono_error_set_type_load_name (error
, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4465 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4468 MonoType
*type
= NULL
;
4469 if (!MONO_HANDLE_IS_NULL (module
)) {
4470 MonoImage
*image
= MONO_HANDLE_GETVAL (module
, image
);
4472 type
= mono_reflection_get_type_checked (image
, image
, &info
, ignoreCase
, &type_resolve
, error
);
4473 if (!is_ok (error
)) {
4475 mono_reflection_free_type_info (&info
);
4481 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4482 if (assembly_is_dynamic (assembly
)) {
4483 /* Enumerate all modules */
4484 MonoReflectionAssemblyBuilderHandle abuilder
= MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder
, NULL
);
4485 MONO_HANDLE_ASSIGN (abuilder
, assembly_h
);
4488 MonoArrayHandle modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
4489 MONO_HANDLE_GET (modules
, abuilder
, modules
);
4490 if (!MONO_HANDLE_IS_NULL (modules
)) {
4491 int n
= mono_array_handle_length (modules
);
4492 for (i
= 0; i
< n
; ++i
) {
4493 type
= get_type_from_module_builder_module (modules
, i
, &info
, ignoreCase
, &type_resolve
, error
);
4494 if (!is_ok (error
)) {
4496 mono_reflection_free_type_info (&info
);
4504 MonoArrayHandle loaded_modules
= MONO_HANDLE_NEW (MonoArray
, NULL
);
4505 MONO_HANDLE_GET (loaded_modules
, abuilder
, loaded_modules
);
4506 if (!type
&& !MONO_HANDLE_IS_NULL (loaded_modules
)) {
4507 int n
= mono_array_handle_length (loaded_modules
);
4508 for (i
= 0; i
< n
; ++i
) {
4509 type
= get_type_from_module_builder_loaded_modules (loaded_modules
, i
, &info
, ignoreCase
, &type_resolve
, error
);
4511 if (!is_ok (error
)) {
4513 mono_reflection_free_type_info (&info
);
4522 type
= mono_reflection_get_type_checked (assembly
->image
, assembly
->image
, &info
, ignoreCase
, &type_resolve
, error
);
4523 if (!is_ok (error
)) {
4525 mono_reflection_free_type_info (&info
);
4531 mono_reflection_free_type_info (&info
);
4535 MonoError inner_error
;
4536 char *typename
= mono_string_handle_to_utf8 (name
, &inner_error
);
4537 mono_error_assert_ok (&inner_error
);
4538 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4539 char *assmname
= mono_stringify_assembly_name (&assembly
->aname
);
4540 mono_error_set_type_load_name (error
, typename
, assmname
, "%s", "");
4544 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4547 if (type
->type
== MONO_TYPE_CLASS
) {
4548 MonoClass
*klass
= mono_type_get_class (type
);
4550 /* need to report exceptions ? */
4551 if (throwOnError
&& mono_class_has_failure (klass
)) {
4552 /* report SecurityException (or others) that occured when loading the assembly */
4553 mono_error_set_for_class_failure (error
, klass
);
4558 /* g_print ("got it\n"); */
4559 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h
), type
, error
);
4561 g_assert (!is_ok (error
));
4562 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
4566 replace_shadow_path (MonoDomain
*domain
, gchar
*dirname
, gchar
**filename
)
4569 gchar
*shadow_ini_file
;
4572 /* Check for shadow-copied assembly */
4573 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4574 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4576 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4577 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4583 g_free (shadow_ini_file
);
4584 if (content
!= NULL
) {
4587 *filename
= content
;
4594 ICALL_EXPORT MonoStringHandle
4595 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly
, MonoBoolean escaped
, MonoError
*error
)
4598 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly
);
4599 MonoAssembly
*mass
= MONO_HANDLE_GETVAL (assembly
, assembly
);
4603 if (g_path_is_absolute (mass
->image
->name
)) {
4604 absolute
= g_strdup (mass
->image
->name
);
4605 dirname
= g_path_get_dirname (absolute
);
4607 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4608 dirname
= g_strdup (mass
->basedir
);
4611 replace_shadow_path (domain
, dirname
, &absolute
);
4614 mono_icall_make_platform_path (absolute
);
4618 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4620 const gchar
*prepend
= mono_icall_get_file_path_prefix (absolute
);
4621 uri
= g_strconcat (prepend
, absolute
, NULL
);
4626 MonoStringHandle res
;
4628 res
= mono_string_new_handle (domain
, uri
, error
);
4631 res
= MONO_HANDLE_NEW (MonoString
, NULL
);
4636 ICALL_EXPORT MonoBoolean
4637 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly
, MonoError
*error
)
4640 MonoAssembly
*mass
= MONO_HANDLE_GETVAL (assembly
,assembly
);
4642 return mass
->in_gac
;
4645 ICALL_EXPORT MonoReflectionAssemblyHandle
4646 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname
, MonoObjectHandle evidence
, MonoError
*error
)
4649 MonoImageOpenStatus status
;
4650 MonoReflectionAssemblyHandle result
= MONO_HANDLE_CAST (MonoReflectionAssembly
, NULL_HANDLE
);
4652 name
= mono_string_handle_to_utf8 (mname
, error
);
4655 MonoAssembly
*res
= mono_assembly_load_with_partial_name (name
, &status
);
4661 result
= mono_assembly_get_object_handle (mono_domain_get (), res
, error
);
4666 ICALL_EXPORT MonoStringHandle
4667 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly
, MonoError
*error
)
4669 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (refassembly
);
4670 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (refassembly
, assembly
);
4671 return mono_string_new_handle (domain
, mono_image_get_filename (assembly
->image
), error
);
4674 ICALL_EXPORT MonoBoolean
4675 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h
, MonoError
*error
)
4678 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4679 return assembly
->ref_only
;
4682 ICALL_EXPORT MonoStringHandle
4683 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly
, MonoError
*error
)
4685 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (refassembly
);
4686 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (refassembly
, assembly
);
4688 return mono_string_new_handle (domain
, assembly
->image
->version
, error
);
4691 ICALL_EXPORT MonoReflectionMethodHandle
4692 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h
, MonoError
*error
)
4695 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_h
);
4696 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4699 MonoReflectionMethodHandle res
= MONO_HANDLE_NEW (MonoReflectionMethod
, NULL
);
4700 guint32 token
= mono_image_get_entry_point (assembly
->image
);
4704 method
= mono_get_method_checked (assembly
->image
, token
, NULL
, NULL
, error
);
4708 MONO_HANDLE_ASSIGN (res
, mono_method_get_object_handle (domain
, method
, NULL
, error
));
4713 ICALL_EXPORT MonoReflectionModuleHandle
4714 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly
, MonoError
*error
)
4717 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly
);
4718 MonoAssembly
*a
= MONO_HANDLE_GETVAL (assembly
, assembly
);
4719 return mono_module_get_object_handle (domain
, a
->image
, error
);
4723 add_manifest_resource_name_to_array (MonoDomain
*domain
, MonoImage
*image
, MonoTableInfo
*table
, int i
, MonoArrayHandle dest
, MonoError
*error
)
4725 HANDLE_FUNCTION_ENTER ();
4727 const char *val
= mono_metadata_string_heap (image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4728 MonoStringHandle str
= mono_string_new_handle (domain
, val
, error
);
4731 MONO_HANDLE_ARRAY_SETREF (dest
, i
, str
);
4733 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
4736 ICALL_EXPORT MonoArrayHandle
4737 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h
, MonoError
*error
)
4740 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_h
);
4741 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4742 MonoTableInfo
*table
= &assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4743 MonoArrayHandle result
= mono_array_new_handle (domain
, mono_defaults
.string_class
, table
->rows
, error
);
4748 for (i
= 0; i
< table
->rows
; ++i
) {
4749 if (!add_manifest_resource_name_to_array (domain
, assembly
->image
, table
, i
, result
, error
))
4754 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
4757 ICALL_EXPORT MonoStringHandle
4758 ves_icall_System_Reflection_Assembly_GetAotId (MonoError
*error
)
4760 char *guid
= mono_runtime_get_aotid ();
4763 MonoStringHandle res
= mono_string_new_handle (mono_domain_get (), guid
, error
);
4768 static MonoAssemblyName
*
4769 create_referenced_assembly_name (MonoDomain
*domain
, MonoImage
*image
, MonoTableInfo
*t
, int i
, MonoError
*error
)
4772 MonoAssemblyName
*aname
= g_new0 (MonoAssemblyName
, 1);
4774 mono_assembly_get_assemblyref (image
, i
, aname
);
4775 aname
->hash_alg
= ASSEMBLY_HASH_SHA1
/* SHA1 (default) */;
4776 /* name and culture are pointers into the image tables, but we need
4777 * real malloc'd strings (so that we can g_free() them later from
4778 * Mono.RuntimeMarshal.FreeAssemblyName) */
4779 aname
->name
= g_strdup (aname
->name
);
4780 aname
->culture
= g_strdup (aname
->culture
);
4781 /* Don't need the hash value in managed */
4782 aname
->hash_value
= NULL
;
4783 aname
->hash_len
= 0;
4784 g_assert (aname
->public_key
== NULL
);
4786 /* note: this function doesn't return the codebase on purpose (i.e. it can
4787 be used under partial trust as path information isn't present). */
4791 ICALL_EXPORT GPtrArray
*
4792 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly
, MonoError
*error
)
4795 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly
);
4796 MonoAssembly
*ass
= MONO_HANDLE_GETVAL(assembly
, assembly
);
4797 MonoImage
*image
= ass
->image
;
4799 MonoTableInfo
*t
= &image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4800 int count
= t
->rows
;
4802 GPtrArray
*result
= g_ptr_array_sized_new (count
);
4804 for (int i
= 0; i
< count
; i
++) {
4805 MonoAssemblyName
*aname
= create_referenced_assembly_name (domain
, image
, t
, i
, error
);
4808 g_ptr_array_add (result
, aname
);
4813 /* move this in some file in mono/util/ */
4815 g_concat_dir_and_file (const char *dir
, const char *file
)
4817 g_return_val_if_fail (dir
!= NULL
, NULL
);
4818 g_return_val_if_fail (file
!= NULL
, NULL
);
4821 * If the directory name doesn't have a / on the end, we need
4822 * to add one so we get a proper path to the file
4824 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4825 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4827 return g_strconcat (dir
, file
, NULL
);
4831 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h
, MonoStringHandle name
, gint32
*size
, MonoReflectionModuleHandleOut ref_module
, MonoError
*error
)
4834 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_h
);
4835 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4836 MonoTableInfo
*table
= &assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4838 guint32 cols
[MONO_MANIFEST_SIZE
];
4839 guint32 impl
, file_idx
;
4843 char *n
= mono_string_handle_to_utf8 (name
, error
);
4844 return_val_if_nok (error
, NULL
);
4846 for (i
= 0; i
< table
->rows
; ++i
) {
4847 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4848 val
= mono_metadata_string_heap (assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4849 if (strcmp (val
, n
) == 0)
4853 if (i
== table
->rows
)
4856 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4859 * this code should only be called after obtaining the
4860 * ResourceInfo and handling the other cases.
4862 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4863 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4865 module
= mono_image_load_file_for_image_checked (assembly
->image
, file_idx
, error
);
4866 if (!is_ok (error
) || !module
)
4870 module
= assembly
->image
;
4873 MonoReflectionModuleHandle rm
= mono_module_get_object_handle (domain
, module
, error
);
4876 MONO_HANDLE_ASSIGN (ref_module
, rm
);
4878 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4882 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h
, MonoStringHandle name
, MonoManifestResourceInfoHandle info
, MonoError
*error
)
4884 HANDLE_FUNCTION_ENTER ();
4885 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_h
);
4886 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4887 MonoTableInfo
*table
= &assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4889 guint32 cols
[MONO_MANIFEST_SIZE
];
4890 guint32 file_cols
[MONO_FILE_SIZE
];
4894 gboolean result
= FALSE
;
4896 n
= mono_string_handle_to_utf8 (name
, error
);
4900 for (i
= 0; i
< table
->rows
; ++i
) {
4901 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4902 val
= mono_metadata_string_heap (assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4903 if (strcmp (val
, n
) == 0)
4907 if (i
== table
->rows
)
4910 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4911 MONO_HANDLE_SETVAL (info
, location
, guint32
, RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
);
4914 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4915 case MONO_IMPLEMENTATION_FILE
:
4916 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4917 table
= &assembly
->image
->tables
[MONO_TABLE_FILE
];
4918 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4919 val
= mono_metadata_string_heap (assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4920 MONO_HANDLE_SET (info
, filename
, mono_string_new_handle (domain
, val
, error
));
4921 if (file_cols
[MONO_FILE_FLAGS
] & FILE_CONTAINS_NO_METADATA
)
4922 MONO_HANDLE_SETVAL (info
, location
, guint32
, 0);
4924 MONO_HANDLE_SETVAL (info
, location
, guint32
, RESOURCE_LOCATION_EMBEDDED
);
4927 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4928 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4929 mono_assembly_load_reference (assembly
->image
, i
- 1);
4930 if (assembly
->image
->references
[i
- 1] == REFERENCE_MISSING
) {
4931 mono_error_set_assembly_load (error
, NULL
, "Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->image
->name
);
4934 MonoReflectionAssemblyHandle assm_obj
= mono_assembly_get_object_handle (mono_domain_get (), assembly
->image
->references
[i
- 1], error
);
4937 MONO_HANDLE_SET (info
, assembly
, assm_obj
);
4939 /* Obtain info recursively */
4940 get_manifest_resource_info_internal (assm_obj
, name
, info
, error
);
4943 guint32 location
= MONO_HANDLE_GETVAL (info
, location
);
4944 location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4945 MONO_HANDLE_SETVAL (info
, location
, guint32
, location
);
4948 case MONO_IMPLEMENTATION_EXP_TYPE
:
4949 g_assert_not_reached ();
4956 HANDLE_FUNCTION_RETURN_VAL (result
);
4959 ICALL_EXPORT gboolean
4960 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h
, MonoStringHandle name
, MonoManifestResourceInfoHandle info_h
, MonoError
*error
)
4963 return get_manifest_resource_info_internal (assembly_h
, name
, info_h
, error
);
4967 add_filename_to_files_array (MonoDomain
*domain
, MonoAssembly
* assembly
, MonoTableInfo
*table
, int i
, MonoArrayHandle dest
, int dest_idx
, MonoError
*error
)
4969 HANDLE_FUNCTION_ENTER();
4971 const char *val
= mono_metadata_string_heap (assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4972 char *n
= g_concat_dir_and_file (assembly
->basedir
, val
);
4973 MonoStringHandle str
= mono_string_new_handle (domain
, n
, error
);
4977 MONO_HANDLE_ARRAY_SETREF (dest
, dest_idx
, str
);
4979 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
4982 ICALL_EXPORT MonoObjectHandle
4983 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h
, MonoStringHandle name
, MonoBoolean resource_modules
, MonoError
*error
)
4986 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_h
);
4987 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
4988 MonoTableInfo
*table
= &assembly
->image
->tables
[MONO_TABLE_FILE
];
4991 /* check hash if needed */
4992 if (!MONO_HANDLE_IS_NULL(name
)) {
4993 char *n
= mono_string_handle_to_utf8 (name
, error
);
4997 for (i
= 0; i
< table
->rows
; ++i
) {
4998 const char *val
= mono_metadata_string_heap (assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4999 if (strcmp (val
, n
) == 0) {
5001 n
= g_concat_dir_and_file (assembly
->basedir
, val
);
5002 MonoStringHandle fn
= mono_string_new_handle (domain
, n
, error
);
5006 return MONO_HANDLE_CAST (MonoObject
, fn
);
5014 for (i
= 0; i
< table
->rows
; ++i
) {
5015 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
5019 MonoArrayHandle result
= mono_array_new_handle (domain
, mono_defaults
.string_class
, count
, error
);
5024 for (i
= 0; i
< table
->rows
; ++i
) {
5025 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5026 if (!add_filename_to_files_array (domain
, assembly
, table
, i
, result
, count
, error
))
5031 return MONO_HANDLE_CAST (MonoObject
, result
);
5037 add_module_to_modules_array (MonoDomain
*domain
, MonoArrayHandle dest
, int *dest_idx
, MonoImage
* module
, MonoError
*error
)
5039 HANDLE_FUNCTION_ENTER ();
5042 MonoReflectionModuleHandle rm
= mono_module_get_object_handle (domain
, module
, error
);
5046 MONO_HANDLE_ARRAY_SETREF (dest
, *dest_idx
, rm
);
5051 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
5055 add_file_to_modules_array (MonoDomain
*domain
, MonoArrayHandle dest
, int dest_idx
, MonoImage
*image
, MonoTableInfo
*table
, int table_idx
, MonoError
*error
)
5057 HANDLE_FUNCTION_ENTER ();
5060 guint32 cols
[MONO_FILE_SIZE
];
5061 mono_metadata_decode_row (table
, table_idx
, cols
, MONO_FILE_SIZE
);
5062 if (cols
[MONO_FILE_FLAGS
] & FILE_CONTAINS_NO_METADATA
) {
5063 MonoReflectionModuleHandle rm
= mono_module_file_get_object_handle (domain
, image
, table_idx
, error
);
5066 MONO_HANDLE_ARRAY_SETREF (dest
, dest_idx
, rm
);
5068 MonoImage
*m
= mono_image_load_file_for_image_checked (image
, table_idx
+ 1, error
);
5072 const char *filename
= mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]);
5073 mono_error_set_assembly_load (error
, g_strdup (filename
), "%s", "");
5076 MonoReflectionModuleHandle rm
= mono_module_get_object_handle (domain
, m
, error
);
5079 MONO_HANDLE_ARRAY_SETREF (dest
, dest_idx
, rm
);
5083 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
5086 ICALL_EXPORT MonoArrayHandle
5087 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h
, MonoError
*error
)
5090 MonoDomain
*domain
= mono_domain_get();
5091 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
5093 int i
, j
, file_count
= 0;
5094 MonoImage
**modules
;
5095 guint32 module_count
, real_module_count
;
5096 MonoTableInfo
*table
;
5097 MonoImage
*image
= assembly
->image
;
5099 g_assert (image
!= NULL
);
5100 g_assert (!assembly_is_dynamic (assembly
));
5102 table
= &image
->tables
[MONO_TABLE_FILE
];
5103 file_count
= table
->rows
;
5105 modules
= image
->modules
;
5106 module_count
= image
->module_count
;
5108 real_module_count
= 0;
5109 for (i
= 0; i
< module_count
; ++i
)
5111 real_module_count
++;
5113 klass
= mono_class_get_module_class ();
5114 MonoArrayHandle res
= mono_array_new_handle (domain
, klass
, 1 + real_module_count
+ file_count
, error
);
5118 MonoReflectionModuleHandle image_obj
= mono_module_get_object_handle (domain
, image
, error
);
5122 MONO_HANDLE_ARRAY_SETREF (res
, 0, image_obj
);
5125 for (i
= 0; i
< module_count
; ++i
)
5126 if (!add_module_to_modules_array (domain
, res
, &j
, modules
[i
], error
))
5129 for (i
= 0; i
< file_count
; ++i
, ++j
) {
5130 if (!add_file_to_modules_array (domain
, res
, j
, image
, table
, i
, error
))
5136 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
5139 ICALL_EXPORT MonoReflectionMethodHandle
5140 ves_icall_GetCurrentMethod (MonoError
*error
)
5144 MonoMethod
*m
= mono_method_get_last_managed ();
5147 mono_error_set_not_supported (error
, "Stack walks are not supported on this platform.");
5148 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
5151 while (m
->is_inflated
)
5152 m
= ((MonoMethodInflated
*)m
)->declaring
;
5154 return mono_method_get_object_handle (mono_domain_get (), m
, NULL
, error
);
5159 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
5162 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
5165 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
5166 //method is inflated, we should inflate it on the other class
5167 MonoGenericContext ctx
;
5168 ctx
.method_inst
= inflated
->context
.method_inst
;
5169 ctx
.class_inst
= inflated
->context
.class_inst
;
5170 if (mono_class_is_ginst (klass
))
5171 ctx
.class_inst
= mono_class_get_generic_class (klass
)->context
.class_inst
;
5172 else if (mono_class_is_gtd (klass
))
5173 ctx
.class_inst
= mono_class_get_generic_container (klass
)->context
.class_inst
;
5174 result
= mono_class_inflate_generic_method_full_checked (inflated
->declaring
, klass
, &ctx
, &error
);
5175 g_assert (mono_error_ok (&error
)); /* FIXME don't swallow the error */
5179 mono_class_setup_methods (method
->klass
);
5180 if (mono_class_has_failure (method
->klass
))
5182 int mcount
= mono_class_get_method_count (method
->klass
);
5183 for (i
= 0; i
< mcount
; ++i
) {
5184 if (method
->klass
->methods
[i
] == method
) {
5189 mono_class_setup_methods (klass
);
5190 if (mono_class_has_failure (klass
))
5192 g_assert (offset
>= 0 && offset
< mono_class_get_method_count (klass
));
5193 return klass
->methods
[offset
];
5196 ICALL_EXPORT MonoReflectionMethodHandle
5197 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod
*method
, MonoType
*type
, MonoBoolean generic_check
, MonoError
*error
)
5201 if (type
&& generic_check
) {
5202 klass
= mono_class_from_mono_type (type
);
5203 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
5204 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
5206 if (method
->klass
!= klass
) {
5207 method
= mono_method_get_equivalent_method (method
, klass
);
5209 return MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
5212 klass
= mono_class_from_mono_type (type
);
5214 klass
= method
->klass
;
5215 return mono_method_get_object_handle (mono_domain_get (), method
, klass
, error
);
5218 ICALL_EXPORT MonoReflectionMethodBodyHandle
5219 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
, MonoError
*error
)
5222 return mono_method_body_get_object_handle (mono_domain_get (), method
, error
);
5225 ICALL_EXPORT MonoReflectionAssemblyHandle
5226 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError
*error
)
5230 MonoMethod
*dest
= NULL
;
5231 mono_stack_walk_no_il (get_executing
, &dest
);
5233 return mono_assembly_get_object_handle (mono_domain_get (), dest
->klass
->image
->assembly
, error
);
5237 ICALL_EXPORT MonoReflectionAssemblyHandle
5238 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError
*error
)
5242 MonoDomain
* domain
= mono_domain_get ();
5244 if (!domain
->entry_assembly
)
5245 return MONO_HANDLE_CAST (MonoReflectionAssembly
, NULL_HANDLE
);
5247 return mono_assembly_get_object_handle (domain
, domain
->entry_assembly
, error
);
5250 ICALL_EXPORT MonoReflectionAssemblyHandle
5251 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError
*error
)
5258 mono_stack_walk_no_il (get_executing
, &dest
);
5260 mono_stack_walk_no_il (get_caller_no_reflection
, &dest
);
5264 mono_error_set_not_supported (error
, "Stack walks are not supported on this platform.");
5265 return MONO_HANDLE_CAST (MonoReflectionAssembly
, NULL_HANDLE
);
5267 return mono_assembly_get_object_handle (mono_domain_get (), dest
->klass
->image
->assembly
, error
);
5270 ICALL_EXPORT MonoStringHandle
5271 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object
, gboolean full_name
,
5272 gboolean assembly_qualified
, MonoError
*error
)
5274 MonoDomain
*domain
= mono_object_domain (MONO_HANDLE_RAW (object
));
5275 MonoType
*type
= MONO_HANDLE_RAW (object
)->type
;
5276 MonoTypeNameFormat format
;
5277 MonoStringHandle res
;
5281 format
= assembly_qualified
?
5282 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
5283 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
5285 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
5287 name
= mono_type_get_name_full (type
, format
);
5289 return NULL_HANDLE_STRING
;
5291 if (full_name
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
)) {
5293 return NULL_HANDLE_STRING
;
5296 res
= mono_string_new_handle (domain
, name
, error
);
5303 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionTypeHandle rfield
, MonoError
*error
)
5306 MonoType
*type
= MONO_HANDLE_GETVAL (rfield
, type
);
5307 MonoClass
*klass
= mono_class_from_mono_type (type
);
5309 mono_class_init_checked (klass
, error
);
5312 return mono_security_core_clr_class_level (klass
);
5316 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField
*rfield
)
5318 MonoClassField
*field
= rfield
->field
;
5319 return mono_security_core_clr_field_level (field
, TRUE
);
5323 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethodHandle rfield
, MonoError
*error
)
5326 MonoMethod
*method
= MONO_HANDLE_GETVAL (rfield
, method
);
5327 return mono_security_core_clr_method_level (method
, TRUE
);
5330 ICALL_EXPORT MonoStringHandle
5331 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly
, MonoError
*error
)
5334 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly
);
5335 MonoAssembly
*mass
= MONO_HANDLE_GETVAL (assembly
, assembly
);
5338 name
= mono_stringify_assembly_name (&mass
->aname
);
5339 MonoStringHandle res
= mono_string_new_handle (domain
, name
, error
);
5344 ICALL_EXPORT MonoAssemblyName
*
5345 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly
*mass
)
5347 return &mass
->aname
;
5351 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname
, MonoAssemblyName
*name
, MonoStringHandleOut normalized_codebase
, MonoError
*error
)
5354 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
5355 char *codebase
= NULL
;
5362 filename
= mono_string_handle_to_utf8 (fname
, error
);
5363 return_if_nok (error
);
5365 dirname
= g_path_get_dirname (filename
);
5366 replace_shadow_path (mono_domain_get (), dirname
, &filename
);
5369 image
= mono_image_open_full (filename
, &status
, TRUE
);
5372 if (status
== MONO_IMAGE_IMAGE_INVALID
)
5373 mono_error_set_bad_image_name (error
, g_strdup (filename
), "%s", "");
5375 mono_error_set_assembly_load (error
, g_strdup (filename
), "%s", "");
5380 res
= mono_assembly_fill_assembly_name_full (image
, name
, TRUE
);
5382 mono_image_close (image
);
5384 mono_error_set_argument (error
, "assemblyFile", "The file does not contain a manifest");
5388 if (filename
!= NULL
&& *filename
!= '\0') {
5391 codebase
= g_strdup (filename
);
5393 mono_icall_make_platform_path (codebase
);
5395 const gchar
*prepend
= mono_icall_get_file_path_prefix (codebase
);
5397 result
= g_strconcat (prepend
, codebase
, NULL
);
5401 MONO_HANDLE_ASSIGN (normalized_codebase
, mono_string_new_handle (mono_domain_get (), codebase
, error
));
5404 mono_image_close (image
);
5408 ICALL_EXPORT MonoBoolean
5409 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h
,
5410 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
, MonoError
*error
)
5413 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_h
, assembly
);
5414 MonoBoolean result
= FALSE
;
5415 MonoDeclSecurityEntry entry
;
5417 /* SecurityAction.RequestMinimum */
5418 if (mono_declsec_get_assembly_action (assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5419 *minimum
= entry
.blob
;
5420 *minLength
= entry
.size
;
5423 /* SecurityAction.RequestOptional */
5424 if (mono_declsec_get_assembly_action (assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5425 *optional
= entry
.blob
;
5426 *optLength
= entry
.size
;
5429 /* SecurityAction.RequestRefuse */
5430 if (mono_declsec_get_assembly_action (assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5431 *refused
= entry
.blob
;
5432 *refLength
= entry
.size
;
5440 mono_module_type_is_visible (MonoTableInfo
*tdef
, MonoImage
*image
, int type
)
5442 guint32 attrs
, visibility
;
5444 attrs
= mono_metadata_decode_row_col (tdef
, type
- 1, MONO_TYPEDEF_FLAGS
);
5445 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5446 if (visibility
!= TYPE_ATTRIBUTE_PUBLIC
&& visibility
!= TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5449 } while ((type
= mono_metadata_token_index (mono_metadata_nested_in_typedef (image
, type
))));
5455 image_get_type (MonoDomain
*domain
, MonoImage
*image
, MonoTableInfo
*tdef
, int table_idx
, int count
, MonoArrayHandle res
, MonoArrayHandle exceptions
, MonoBoolean exportedOnly
, MonoError
*error
)
5458 HANDLE_FUNCTION_ENTER ();
5459 MonoError klass_error
;
5460 MonoClass
*klass
= mono_class_get_checked (image
, table_idx
| MONO_TOKEN_TYPE_DEF
, &klass_error
);
5463 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
5464 return_if_nok (error
);
5466 MONO_HANDLE_ARRAY_SETREF (res
, count
, rt
);
5468 MonoException
*ex
= mono_error_convert_to_exception (error
);
5469 MONO_HANDLE_ARRAY_SETRAW (exceptions
, count
, ex
);
5471 HANDLE_FUNCTION_RETURN ();
5474 static MonoArrayHandle
5475 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArrayHandleOut exceptions
, MonoBoolean exportedOnly
, MonoError
*error
)
5477 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5482 /* we start the count from 1 because we skip the special type <Module> */
5485 for (i
= 1; i
< tdef
->rows
; ++i
) {
5486 if (mono_module_type_is_visible (tdef
, image
, i
+ 1))
5490 count
= tdef
->rows
- 1;
5492 MonoArrayHandle res
= mono_array_new_handle (domain
, mono_defaults
.runtimetype_class
, count
, error
);
5493 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5494 MONO_HANDLE_ASSIGN (exceptions
, mono_array_new_handle (domain
, mono_defaults
.exception_class
, count
, error
));
5495 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5497 for (i
= 1; i
< tdef
->rows
; ++i
) {
5498 if (!exportedOnly
|| mono_module_type_is_visible (tdef
, image
, i
+1)) {
5499 image_get_type (domain
, image
, tdef
, i
+ 1, count
, res
, exceptions
, exportedOnly
, error
);
5500 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5509 append_module_types (MonoDomain
*domain
, MonoArrayHandleOut res
, MonoArrayHandleOut exceptions
, MonoImage
*image
, MonoBoolean exportedOnly
, MonoError
*error
)
5511 HANDLE_FUNCTION_ENTER ();
5513 MonoArrayHandle ex2
= MONO_HANDLE_NEW (MonoArray
, NULL
);
5514 MonoArrayHandle res2
= mono_module_get_types (domain
, image
, ex2
, exportedOnly
, error
);
5518 /* Append the new types to the end of the array */
5519 if (mono_array_handle_length (res2
) > 0) {
5522 len1
= mono_array_handle_length (res
);
5523 len2
= mono_array_handle_length (res2
);
5525 MonoArrayHandle res3
= mono_array_new_handle (domain
, mono_defaults
.runtimetype_class
, len1
+ len2
, error
);
5529 mono_array_handle_memcpy_refs (res3
, 0, res
, 0, len1
);
5530 mono_array_handle_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5531 MONO_HANDLE_ASSIGN (res
, res3
);
5533 MonoArrayHandle ex3
= mono_array_new_handle (domain
, mono_defaults
.runtimetype_class
, len1
+ len2
, error
);
5537 mono_array_handle_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5538 mono_array_handle_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5539 MONO_HANDLE_ASSIGN (exceptions
, ex3
);
5542 HANDLE_FUNCTION_RETURN ();
5546 set_class_failure_in_array (MonoArrayHandle exl
, int i
, MonoClass
*klass
)
5548 HANDLE_FUNCTION_ENTER ();
5549 MonoError unboxed_error
;
5550 error_init (&unboxed_error
);
5551 mono_error_set_for_class_failure (&unboxed_error
, klass
);
5553 MonoExceptionHandle exc
= MONO_HANDLE_NEW (MonoException
, mono_error_convert_to_exception (&unboxed_error
));
5554 MONO_HANDLE_ARRAY_SETREF (exl
, i
, exc
);
5555 HANDLE_FUNCTION_RETURN ();
5558 ICALL_EXPORT MonoArrayHandle
5559 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle
, MonoBoolean exportedOnly
, MonoError
*error
)
5561 MonoArrayHandle exceptions
= MONO_HANDLE_NEW(MonoArray
, NULL
);
5564 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (assembly_handle
);
5565 MonoAssembly
*assembly
= MONO_HANDLE_GETVAL (assembly_handle
, assembly
);
5567 g_assert (!assembly_is_dynamic (assembly
));
5568 MonoImage
*image
= assembly
->image
;
5569 MonoTableInfo
*table
= &image
->tables
[MONO_TABLE_FILE
];
5570 MonoArrayHandle res
= mono_module_get_types (domain
, image
, exceptions
, exportedOnly
, error
);
5571 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5573 /* Append data from all modules in the assembly */
5574 for (i
= 0; i
< table
->rows
; ++i
) {
5575 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5576 MonoImage
*loaded_image
= mono_assembly_load_module_checked (image
->assembly
, i
+ 1, error
);
5577 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5580 append_module_types (domain
, res
, exceptions
, loaded_image
, exportedOnly
, error
);
5581 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
));
5586 /* the ReflectionTypeLoadException must have all the types (Types property),
5587 * NULL replacing types which throws an exception. The LoaderException must
5588 * contain all exceptions for NULL items.
5591 int len
= mono_array_handle_length (res
);
5595 MonoReflectionTypeHandle t
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
5596 for (i
= 0; i
< len
; i
++) {
5597 MONO_HANDLE_ARRAY_GETREF (t
, res
, i
);
5599 if (!MONO_HANDLE_IS_NULL (t
)) {
5600 MonoClass
*klass
= mono_type_get_class (MONO_HANDLE_GETVAL (t
, type
));
5601 if ((klass
!= NULL
) && mono_class_has_failure (klass
)) {
5602 /* keep the class in the list */
5603 list
= g_list_append (list
, klass
);
5604 /* and replace Type with NULL */
5605 MONO_HANDLE_ARRAY_SETRAW (res
, i
, NULL
);
5612 if (list
|| ex_count
) {
5614 int j
, length
= g_list_length (list
) + ex_count
;
5616 MonoArrayHandle exl
= mono_array_new_handle (domain
, mono_defaults
.exception_class
, length
, error
);
5617 if (!is_ok (error
)) {
5619 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
5621 /* Types for which mono_class_get_checked () succeeded */
5622 MonoExceptionHandle exc
= MONO_HANDLE_NEW (MonoException
, NULL
);
5623 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5624 set_class_failure_in_array (exl
, i
, (MonoClass
*)tmp
->data
);
5626 /* Types for which it don't */
5627 for (j
= 0; j
< mono_array_handle_length (exceptions
); ++j
) {
5628 MONO_HANDLE_ARRAY_GETREF (exc
, exceptions
, j
);
5629 if (!MONO_HANDLE_IS_NULL (exc
)) {
5630 g_assert (i
< length
);
5631 MONO_HANDLE_ARRAY_SETREF (exl
, i
, exc
);
5638 MONO_HANDLE_ASSIGN (exc
, mono_get_exception_reflection_type_load_checked (res
, exl
, error
));
5639 if (!is_ok (error
)) {
5640 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
5642 mono_error_set_exception_handle (error
, exc
);
5643 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
5650 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName
*aname
, gboolean free_struct
)
5652 mono_assembly_name_free (aname
);
5657 ICALL_EXPORT gboolean
5658 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name
, MonoAssemblyName
*aname
, gboolean
*is_version_definited
, gboolean
*is_token_defined
)
5660 *is_version_definited
= *is_token_defined
= FALSE
;
5662 return mono_assembly_name_parse_full (name
, aname
, TRUE
, is_version_definited
, is_token_defined
);
5665 ICALL_EXPORT MonoReflectionTypeHandle
5666 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module
, MonoError
*error
)
5668 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (module
);
5669 MonoImage
*image
= MONO_HANDLE_GETVAL (module
, image
);
5674 MonoReflectionTypeHandle ret
= MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
5676 if (image_is_dynamic (image
) && ((MonoDynamicImage
*)image
)->initial_image
)
5677 /* These images do not have a global type */
5680 klass
= mono_class_get_checked (image
, 1 | MONO_TOKEN_TYPE_DEF
, error
);
5684 ret
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
5690 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module
, MonoError
*error
)
5692 /*if (module->image)
5693 mono_image_close (module->image);*/
5696 ICALL_EXPORT MonoStringHandle
5697 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule
, MonoError
*error
)
5699 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (refmodule
);
5700 MonoImage
*image
= MONO_HANDLE_GETVAL (refmodule
, image
);
5703 return mono_string_new_handle (domain
, image
->guid
, error
);
5707 static inline gpointer
5708 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module
)
5710 return (gpointer
) (-1);
5712 #endif /* HOST_WIN32 */
5714 ICALL_EXPORT gpointer
5715 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module
, MonoError
*error
)
5717 return mono_icall_module_get_hinstance (module
);
5721 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
, MonoError
*error
)
5723 if (image_is_dynamic (image
)) {
5724 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5725 *pe_kind
= dyn
->pe_kind
;
5726 *machine
= dyn
->machine
;
5729 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5730 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5735 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
, MonoError
*error
)
5737 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5740 ICALL_EXPORT MonoArrayHandle
5741 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module
, MonoError
*error
)
5745 MonoImage
*image
= MONO_HANDLE_GETVAL (module
, image
);
5746 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (module
);
5749 MonoArrayHandle arr
= mono_array_new_handle (domain
, mono_defaults
.runtimetype_class
, 0, error
);
5752 MonoArrayHandle exceptions
= MONO_HANDLE_NEW (MonoArray
, NULL
);
5753 MonoArrayHandle res
= mono_module_get_types (domain
, image
, exceptions
, FALSE
, error
);
5754 return_val_if_nok (error
, MONO_HANDLE_CAST(MonoArray
, NULL_HANDLE
));
5756 int n
= mono_array_handle_length (exceptions
);
5757 MonoExceptionHandle ex
= MONO_HANDLE_NEW (MonoException
, NULL
);
5758 for (int i
= 0; i
< n
; ++i
) {
5759 MONO_HANDLE_ARRAY_GETREF(ex
, exceptions
, i
);
5760 if (!MONO_HANDLE_IS_NULL (ex
)) {
5761 mono_error_set_exception_handle (error
, ex
);
5762 return MONO_HANDLE_CAST(MonoArray
, NULL_HANDLE
);
5770 mono_memberref_is_method (MonoImage
*image
, guint32 token
)
5772 if (!image_is_dynamic (image
)) {
5773 guint32 cols
[MONO_MEMBERREF_SIZE
];
5775 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5776 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5777 mono_metadata_decode_blob_size (sig
, &sig
);
5778 return (*sig
!= 0x6);
5781 MonoClass
*handle_class
;
5783 if (!mono_lookup_dynamic_token_class (image
, token
, FALSE
, &handle_class
, NULL
, &error
)) {
5784 mono_error_cleanup (&error
); /* just probing, ignore error */
5788 return mono_defaults
.methodhandle_class
== handle_class
;
5792 static MonoGenericInst
*
5793 get_generic_inst_from_array_handle (MonoArrayHandle type_args
)
5795 int type_argc
= mono_array_handle_length (type_args
);
5796 int size
= MONO_SIZEOF_GENERIC_INST
+ type_argc
* sizeof (MonoType
*);
5798 MonoGenericInst
*ginst
= (MonoGenericInst
*)g_alloca (size
);
5799 memset (ginst
, 0, sizeof (MonoGenericInst
));
5800 ginst
->type_argc
= type_argc
;
5801 for (int i
= 0; i
< type_argc
; i
++) {
5802 MONO_HANDLE_ARRAY_GETVAL (ginst
->type_argv
[i
], type_args
, MonoType
*, i
);
5804 ginst
->is_open
= FALSE
;
5805 for (int i
= 0; i
< type_argc
; i
++) {
5806 if (mono_class_is_open_constructed_type (ginst
->type_argv
[i
])) {
5807 ginst
->is_open
= TRUE
;
5812 return mono_metadata_get_canonical_generic_inst (ginst
);
5816 init_generic_context_from_args_handles (MonoGenericContext
*context
, MonoArrayHandle type_args
, MonoArrayHandle method_args
)
5818 if (!MONO_HANDLE_IS_NULL (type_args
)) {
5819 context
->class_inst
= get_generic_inst_from_array_handle (type_args
);
5821 context
->class_inst
= NULL
;
5823 if (!MONO_HANDLE_IS_NULL (method_args
)) {
5824 context
->method_inst
= get_generic_inst_from_array_handle (method_args
);
5826 context
->method_inst
= NULL
;
5832 module_resolve_type_token (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
5834 HANDLE_FUNCTION_ENTER ();
5836 MonoType
*result
= NULL
;
5838 int table
= mono_metadata_token_table (token
);
5839 int index
= mono_metadata_token_index (token
);
5840 MonoGenericContext context
;
5842 *resolve_error
= ResolveTokenError_Other
;
5844 /* Validate token */
5845 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5846 (table
!= MONO_TABLE_TYPESPEC
)) {
5847 *resolve_error
= ResolveTokenError_BadTable
;
5851 if (image_is_dynamic (image
)) {
5852 if ((table
== MONO_TABLE_TYPEDEF
) || (table
== MONO_TABLE_TYPEREF
)) {
5853 MonoError inner_error
;
5854 klass
= (MonoClass
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
, &inner_error
);
5855 mono_error_cleanup (&inner_error
);
5856 result
= klass
? &klass
->byval_arg
: NULL
;
5860 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
5861 MonoError inner_error
;
5862 klass
= (MonoClass
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, &context
, &inner_error
);
5863 mono_error_cleanup (&inner_error
);
5864 result
= klass
? &klass
->byval_arg
: NULL
;
5868 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5869 *resolve_error
= ResolveTokenError_OutOfRange
;
5873 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
5874 klass
= mono_class_get_checked (image
, token
, error
);
5876 klass
= mono_class_inflate_generic_class_checked (klass
, &context
, error
);
5881 result
= &klass
->byval_arg
;
5883 HANDLE_FUNCTION_RETURN_VAL (result
);
5886 ICALL_EXPORT MonoType
*
5887 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
5889 return module_resolve_type_token (image
, token
, type_args
, method_args
, resolve_error
, error
);
5893 module_resolve_method_token (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
5895 HANDLE_FUNCTION_ENTER ();
5897 MonoMethod
*method
= NULL
;
5898 int table
= mono_metadata_token_table (token
);
5899 int index
= mono_metadata_token_index (token
);
5900 MonoGenericContext context
;
5902 *resolve_error
= ResolveTokenError_Other
;
5904 /* Validate token */
5905 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5906 (table
!= MONO_TABLE_MEMBERREF
)) {
5907 *resolve_error
= ResolveTokenError_BadTable
;
5911 if (image_is_dynamic (image
)) {
5912 if (table
== MONO_TABLE_METHOD
) {
5913 MonoError inner_error
;
5914 method
= (MonoMethod
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
, &inner_error
);
5915 mono_error_cleanup (&inner_error
);
5919 if ((table
== MONO_TABLE_MEMBERREF
) && !(mono_memberref_is_method (image
, token
))) {
5920 *resolve_error
= ResolveTokenError_BadTable
;
5924 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
5925 MonoError inner_error
;
5926 method
= (MonoMethod
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, &context
, &inner_error
);
5927 mono_error_cleanup (&inner_error
);
5931 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5932 *resolve_error
= ResolveTokenError_OutOfRange
;
5935 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_memberref_is_method (image
, token
))) {
5936 *resolve_error
= ResolveTokenError_BadTable
;
5940 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
5941 method
= mono_get_method_checked (image
, token
, NULL
, &context
, error
);
5944 HANDLE_FUNCTION_RETURN_VAL (method
);
5947 ICALL_EXPORT MonoMethod
*
5948 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
5950 return module_resolve_method_token (image
, token
, type_args
, method_args
, resolve_error
, error
);
5953 ICALL_EXPORT MonoString
*
5954 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*resolve_error
)
5957 int index
= mono_metadata_token_index (token
);
5959 *resolve_error
= ResolveTokenError_Other
;
5961 /* Validate token */
5962 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5963 *resolve_error
= ResolveTokenError_BadTable
;
5967 if (image_is_dynamic (image
)) {
5968 MonoString
* result
= (MonoString
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
, &error
);
5969 mono_error_cleanup (&error
);
5973 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5974 *resolve_error
= ResolveTokenError_OutOfRange
;
5978 /* FIXME: What to do if the index points into the middle of a string ? */
5980 MonoString
*result
= mono_ldstr_checked (mono_domain_get (), image
, index
, &error
);
5981 mono_error_set_pending_exception (&error
);
5985 static MonoClassField
*
5986 module_resolve_field_token (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
5988 HANDLE_FUNCTION_ENTER ();
5990 int table
= mono_metadata_token_table (token
);
5991 int index
= mono_metadata_token_index (token
);
5992 MonoGenericContext context
;
5993 MonoClassField
*field
= NULL
;
5996 *resolve_error
= ResolveTokenError_Other
;
5998 /* Validate token */
5999 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
6000 *resolve_error
= ResolveTokenError_BadTable
;
6004 if (image_is_dynamic (image
)) {
6005 if (table
== MONO_TABLE_FIELD
) {
6006 MonoError inner_error
;
6007 field
= (MonoClassField
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
, &inner_error
);
6008 mono_error_cleanup (&inner_error
);
6012 if (mono_memberref_is_method (image
, token
)) {
6013 *resolve_error
= ResolveTokenError_BadTable
;
6017 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
6018 MonoError inner_error
;
6019 field
= (MonoClassField
*)mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, &context
, &inner_error
);
6020 mono_error_cleanup (&inner_error
);
6024 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
6025 *resolve_error
= ResolveTokenError_OutOfRange
;
6028 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_memberref_is_method (image
, token
))) {
6029 *resolve_error
= ResolveTokenError_BadTable
;
6033 init_generic_context_from_args_handles (&context
, type_args
, method_args
);
6034 field
= mono_field_from_token_checked (image
, token
, &klass
, &context
, error
);
6037 HANDLE_FUNCTION_RETURN_VAL (field
);
6040 ICALL_EXPORT MonoClassField
*
6041 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
6043 return module_resolve_field_token (image
, token
, type_args
, method_args
, resolve_error
, error
);
6046 ICALL_EXPORT MonoObjectHandle
6047 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArrayHandle type_args
, MonoArrayHandle method_args
, MonoResolveTokenError
*error
, MonoError
*merror
)
6049 int table
= mono_metadata_token_table (token
);
6051 error_init (merror
);
6052 *error
= ResolveTokenError_Other
;
6055 case MONO_TABLE_TYPEDEF
:
6056 case MONO_TABLE_TYPEREF
:
6057 case MONO_TABLE_TYPESPEC
: {
6058 MonoType
*t
= module_resolve_type_token (image
, token
, type_args
, method_args
, error
, merror
);
6060 return MONO_HANDLE_CAST (MonoObject
, mono_type_get_object_handle (mono_domain_get (), t
, merror
));
6065 case MONO_TABLE_METHOD
:
6066 case MONO_TABLE_METHODSPEC
: {
6067 MonoMethod
*m
= module_resolve_method_token (image
, token
, type_args
, method_args
, error
, merror
);
6069 return MONO_HANDLE_CAST (MonoObject
, mono_method_get_object_handle (mono_domain_get (), m
, m
->klass
, merror
));
6073 case MONO_TABLE_FIELD
: {
6074 MonoClassField
*f
= module_resolve_field_token (image
, token
, type_args
, method_args
, error
, merror
);
6076 return MONO_HANDLE_CAST (MonoObject
, mono_field_get_object_handle (mono_domain_get (), f
->parent
, f
, merror
));
6081 case MONO_TABLE_MEMBERREF
:
6082 if (mono_memberref_is_method (image
, token
)) {
6083 MonoMethod
*m
= module_resolve_method_token (image
, token
, type_args
, method_args
, error
, merror
);
6085 return MONO_HANDLE_CAST (MonoObject
, mono_method_get_object_handle (mono_domain_get (), m
, m
->klass
, merror
));
6090 MonoClassField
*f
= module_resolve_field_token (image
, token
, type_args
, method_args
, error
, merror
);
6092 return MONO_HANDLE_CAST (MonoObject
, mono_field_get_object_handle (mono_domain_get (), f
->parent
, f
, merror
));
6100 *error
= ResolveTokenError_BadTable
;
6106 ICALL_EXPORT MonoArrayHandle
6107 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*resolve_error
, MonoError
*error
)
6110 int table
= mono_metadata_token_table (token
);
6111 int idx
= mono_metadata_token_index (token
);
6112 MonoTableInfo
*tables
= image
->tables
;
6116 *resolve_error
= ResolveTokenError_OutOfRange
;
6118 /* FIXME: Support other tables ? */
6119 if (table
!= MONO_TABLE_STANDALONESIG
)
6120 return MONO_HANDLE_CAST (MonoArray
, NULL
);
6122 if (image_is_dynamic (image
))
6123 return MONO_HANDLE_CAST (MonoArray
, NULL
);
6125 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
6126 return MONO_HANDLE_CAST (MonoArray
, NULL
);
6128 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
6130 ptr
= mono_metadata_blob_heap (image
, sig
);
6131 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
6133 MonoArrayHandle res
= mono_array_new_handle (mono_domain_get (), mono_defaults
.byte_class
, len
, error
);
6135 return MONO_HANDLE_CAST (MonoArray
, NULL
);
6137 gpointer array_base
= MONO_ARRAY_HANDLE_PIN (res
, guint8
, 0, &h
);
6138 memcpy (array_base
, ptr
, len
);
6139 mono_gchandle_free (h
);
6143 ICALL_EXPORT MonoBoolean
6144 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
6147 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
6149 MonoBoolean res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
6155 check_for_invalid_type (MonoClass
*klass
, MonoError
*error
)
6161 if (klass
->byval_arg
.type
!= MONO_TYPE_TYPEDBYREF
)
6164 name
= mono_type_get_full_name (klass
);
6165 mono_error_set_type_load_name (error
, name
, g_strdup (""), "");
6168 ICALL_EXPORT MonoReflectionTypeHandle
6169 ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type
, int rank
, MonoError
*error
)
6172 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
6174 MonoClass
*klass
= mono_class_from_mono_type (type
);
6175 check_for_invalid_type (klass
, error
);
6177 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6180 if (rank
== 0) //single dimentional array
6181 aklass
= mono_array_class_get (klass
, 1);
6183 aklass
= mono_bounded_array_class_get (klass
, rank
, TRUE
);
6185 if (mono_class_has_failure (aklass
)) {
6186 mono_error_set_for_class_failure (error
, aklass
);
6187 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6190 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
6191 return mono_type_get_object_handle (domain
, &aklass
->byval_arg
, error
);
6194 ICALL_EXPORT MonoReflectionTypeHandle
6195 ves_icall_RuntimeType_make_byref_type (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
6198 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
6200 MonoClass
*klass
= mono_class_from_mono_type (type
);
6201 mono_class_init_checked (klass
, error
);
6203 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6205 check_for_invalid_type (klass
, error
);
6207 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6209 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
6210 return mono_type_get_object_handle (domain
, &klass
->this_arg
, error
);
6213 ICALL_EXPORT MonoReflectionTypeHandle
6214 ves_icall_RuntimeType_MakePointerType (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
6217 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
6218 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
6219 MonoClass
*klass
= mono_class_from_mono_type (type
);
6220 mono_class_init_checked (klass
, error
);
6222 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6224 check_for_invalid_type (klass
, error
);
6226 return MONO_HANDLE_CAST (MonoReflectionType
, NULL_HANDLE
);
6228 MonoClass
*pklass
= mono_ptr_class_get (type
);
6230 return mono_type_get_object_handle (domain
, &pklass
->byval_arg
, error
);
6233 ICALL_EXPORT MonoObjectHandle
6234 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionTypeHandle ref_type
, MonoObjectHandle target
,
6235 MonoReflectionMethodHandle info
, MonoBoolean throwOnBindFailure
, MonoError
*error
)
6237 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
6238 MonoClass
*delegate_class
= mono_class_from_mono_type (type
);
6240 MonoMethod
*method
= MONO_HANDLE_GETVAL (info
, method
);
6241 MonoMethodSignature
*sig
= mono_method_signature(method
);
6243 mono_class_init_checked (delegate_class
, error
);
6244 return_val_if_nok (error
, NULL_HANDLE
);
6246 if (!(delegate_class
->parent
== mono_defaults
.multicastdelegate_class
)) {
6247 /* FIXME improve this exception message */
6248 mono_error_set_execution_engine (error
, "file %s: line %d (%s): assertion failed: (%s)", __FILE__
, __LINE__
,
6250 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6254 if (mono_security_core_clr_enabled ()) {
6255 MonoError security_error
;
6256 if (!mono_security_core_clr_ensure_delegate_creation (method
, &security_error
)) {
6257 if (throwOnBindFailure
)
6258 mono_error_move (error
, &security_error
);
6260 mono_error_cleanup (&security_error
);
6265 if (sig
->generic_param_count
&& method
->wrapper_type
== MONO_WRAPPER_NONE
) {
6266 if (!method
->is_inflated
) {
6267 mono_error_set_argument (error
, "method", " Cannot bind to the target method because its signature differs from that of the delegate type");
6272 MonoObjectHandle delegate
= MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (MONO_HANDLE_DOMAIN (ref_type
), delegate_class
, error
));
6273 return_val_if_nok (error
, NULL_HANDLE
);
6275 if (method_is_dynamic (method
)) {
6276 /* Creating a trampoline would leak memory */
6277 func
= mono_compile_method_checked (method
, error
);
6278 return_val_if_nok (error
, NULL_HANDLE
);
6280 if (!MONO_HANDLE_IS_NULL (target
) && method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
&& method
->klass
!= mono_handle_class (target
)) {
6281 method
= mono_object_handle_get_virtual_method (target
, method
, error
);
6282 return_val_if_nok (error
, NULL_HANDLE
);
6284 gpointer trampoline
= mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
, error
);
6285 return_val_if_nok (error
, NULL_HANDLE
);
6286 func
= mono_create_ftnptr (mono_domain_get (), trampoline
);
6289 mono_delegate_ctor_with_method (delegate
, target
, func
, method
, error
);
6290 return_val_if_nok (error
, NULL_HANDLE
);
6294 ICALL_EXPORT MonoMulticastDelegateHandle
6295 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegateHandle delegate
, MonoError
*error
)
6299 MonoClass
*klass
= mono_handle_class (delegate
);
6300 g_assert (mono_class_has_parent (klass
, mono_defaults
.multicastdelegate_class
));
6302 MonoMulticastDelegateHandle ret
= MONO_HANDLE_NEW (MonoMulticastDelegate
, mono_object_new_checked (MONO_HANDLE_DOMAIN (delegate
), klass
, error
));
6303 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoMulticastDelegate
, NULL_HANDLE
));
6305 MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoDelegate
, ret
), invoke_impl
, gpointer
, mono_runtime_create_delegate_trampoline (klass
));
6310 ICALL_EXPORT MonoReflectionMethodHandle
6311 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegateHandle delegate
, MonoError
*error
)
6315 MonoObjectHandle delegate_target
= MONO_HANDLE_NEW_GET (MonoObject
, delegate
, target
);
6316 MonoMethod
*m
= mono_object_handle_get_virtual_method (delegate_target
, MONO_HANDLE_GETVAL (delegate
, method
), error
);
6317 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
));
6318 return mono_method_get_object_handle (mono_domain_get (), m
, m
->klass
, error
);
6323 static inline gint32
6324 mono_array_get_byte_length (MonoArray
*array
)
6330 klass
= array
->obj
.vtable
->klass
;
6332 if (array
->bounds
== NULL
)
6333 length
= array
->max_length
;
6336 for (i
= 0; i
< klass
->rank
; ++ i
)
6337 length
*= array
->bounds
[i
].length
;
6340 switch (klass
->element_class
->byval_arg
.type
) {
6343 case MONO_TYPE_BOOLEAN
:
6347 case MONO_TYPE_CHAR
:
6355 return length
* sizeof (gpointer
);
6366 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6368 return mono_array_get_byte_length (array
);
6372 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6374 return mono_array_get (array
, gint8
, idx
);
6378 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6380 mono_array_set (array
, gint8
, idx
, value
);
6383 ICALL_EXPORT MonoBoolean
6384 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6386 guint8
*src_buf
, *dest_buf
;
6389 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6393 g_assert (count
>= 0);
6395 /* This is called directly from the class libraries without going through the managed wrapper */
6396 MONO_CHECK_ARG_NULL (src
, FALSE
);
6397 MONO_CHECK_ARG_NULL (dest
, FALSE
);
6399 /* watch out for integer overflow */
6400 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6403 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6404 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6407 memcpy (dest_buf
, src_buf
, count
);
6409 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6414 #ifndef DISABLE_REMOTING
6415 ICALL_EXPORT MonoObjectHandle
6416 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObjectHandle this_obj
, MonoStringHandle class_name
, MonoError
*error
)
6419 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (this_obj
);
6420 MonoRealProxyHandle rp
= MONO_HANDLE_CAST (MonoRealProxy
, this_obj
);
6422 MonoObjectHandle res
= MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (domain
, mono_defaults
.transparent_proxy_class
, error
));
6426 MonoTransparentProxyHandle tp
= MONO_HANDLE_CAST (MonoTransparentProxy
, res
);
6428 MONO_HANDLE_SET (tp
, rp
, rp
);
6430 MonoReflectionTypeHandle reftype
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
6431 MONO_HANDLE_GET (reftype
, rp
, class_to_proxy
);
6432 MonoType
*type
= MONO_HANDLE_GETVAL (reftype
, type
);
6433 MonoClass
*klass
= mono_class_from_mono_type (type
);
6435 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6436 mono_class_setup_vtable (klass
);
6437 if (mono_class_has_failure (klass
)) {
6438 mono_error_set_for_class_failure (error
, klass
);
6442 MonoObjectHandle remoting_obj
= mono_object_handle_isinst (this_obj
, mono_defaults
.iremotingtypeinfo_class
, error
);
6445 MONO_HANDLE_SETVAL (tp
, custom_type_info
, MonoBoolean
, !MONO_HANDLE_IS_NULL (remoting_obj
));
6447 MonoRemoteClass
*remote_class
= mono_remote_class (domain
, class_name
, klass
, error
);
6450 MONO_HANDLE_SETVAL (tp
, remote_class
, MonoRemoteClass
*, remote_class
);
6452 MONO_HANDLE_SETVAL (res
, vtable
, MonoVTable
*, mono_remote_class_vtable (domain
, remote_class
, rp
, error
));
6458 ICALL_EXPORT MonoReflectionType
*
6459 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6462 g_assert (tp
!= NULL
&& mono_object_class (tp
) == mono_defaults
.transparent_proxy_class
);
6463 g_assert (tp
->remote_class
!= NULL
&& tp
->remote_class
->proxy_class
!= NULL
);
6464 MonoReflectionType
*ret
= mono_type_get_object_checked (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
, &error
);
6465 mono_error_set_pending_exception (&error
);
6471 /* System.Environment */
6474 ves_icall_System_Environment_get_UserName (MonoError
*error
)
6477 /* using glib is more portable */
6478 return mono_string_new_handle (mono_domain_get (), g_get_user_name (), error
);
6482 static MonoStringHandle
6483 mono_icall_get_machine_name (MonoError
*error
)
6486 #if !defined(DISABLE_SOCKETS)
6487 MonoStringHandle result
;
6490 #if defined _SC_HOST_NAME_MAX
6491 n
= sysconf (_SC_HOST_NAME_MAX
);
6495 buf
= g_malloc (n
+1);
6497 if (gethostname (buf
, n
) == 0){
6499 result
= mono_string_new_handle (mono_domain_get (), buf
, error
);
6501 result
= MONO_HANDLE_CAST (MonoString
, NULL_HANDLE
);
6506 return mono_string_new_handle (mono_domain_get (), "mono", error
);
6509 #endif /* !HOST_WIN32 */
6511 ICALL_EXPORT MonoStringHandle
6512 ves_icall_System_Environment_get_MachineName (MonoError
*error
)
6515 return mono_icall_get_machine_name (error
);
6520 mono_icall_get_platform (void)
6522 #if defined(__MACH__)
6525 // Notice that the value is hidden from user code, and only exposed
6526 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6527 // define and making assumptions based on Unix/128/4 values before there
6528 // was a MacOS define. Lots of code would assume that not-Unix meant
6529 // Windows, but in this case, it would be OSX.
6537 #endif /* !HOST_WIN32 */
6540 ves_icall_System_Environment_get_Platform (void)
6542 return mono_icall_get_platform ();
6546 static inline MonoStringHandle
6547 mono_icall_get_new_line (MonoError
*error
)
6550 return mono_string_new_handle (mono_domain_get (), "\n", error
);
6552 #endif /* !HOST_WIN32 */
6554 ICALL_EXPORT MonoStringHandle
6555 ves_icall_System_Environment_get_NewLine (MonoError
*error
)
6557 return mono_icall_get_new_line (error
);
6561 static inline MonoBoolean
6562 mono_icall_is_64bit_os (void)
6564 #if SIZEOF_VOID_P == 8
6567 #if defined(HAVE_SYS_UTSNAME_H)
6568 struct utsname name
;
6570 if (uname (&name
) >= 0) {
6571 return strcmp (name
.machine
, "x86_64") == 0 || strncmp (name
.machine
, "aarch64", 7) == 0 || strncmp (name
.machine
, "ppc64", 5) == 0;
6577 #endif /* !HOST_WIN32 */
6579 ICALL_EXPORT MonoBoolean
6580 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6582 return mono_icall_is_64bit_os ();
6585 ICALL_EXPORT MonoStringHandle
6586 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar
*utf8_name
, MonoError
*error
)
6590 if (utf8_name
== NULL
)
6591 return NULL_HANDLE_STRING
;
6593 value
= g_getenv (utf8_name
);
6596 return NULL_HANDLE_STRING
;
6598 MonoStringHandle res
= mono_string_new_handle (mono_domain_get (), value
, error
);
6604 * There is no standard way to get at environ.
6607 #ifndef __MINGW32_VERSION
6608 #if defined(__APPLE__)
6609 #if defined (TARGET_OSX)
6610 /* Apple defines this in crt_externs.h but doesn't provide that header for
6611 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6612 * in fact exist on all implementations (so far)
6614 gchar
***_NSGetEnviron(void);
6615 #define environ (*_NSGetEnviron())
6617 static char *mono_environ
[1] = { NULL
};
6618 #define environ mono_environ
6619 #endif /* defined (TARGET_OSX) */
6627 ICALL_EXPORT MonoArray
*
6628 ves_icall_System_Environment_GetCommandLineArgs (void)
6631 MonoArray
*result
= mono_runtime_get_main_args_checked (&error
);
6632 mono_error_set_pending_exception (&error
);
6638 mono_icall_get_environment_variable_names (MonoError
*error
)
6648 for (e
= environ
; *e
!= 0; ++ e
)
6651 domain
= mono_domain_get ();
6652 names
= mono_array_new_checked (domain
, mono_defaults
.string_class
, n
, error
);
6653 return_val_if_nok (error
, NULL
);
6656 for (e
= environ
; *e
!= 0; ++ e
) {
6657 parts
= g_strsplit (*e
, "=", 2);
6659 str
= mono_string_new_checked (domain
, *parts
, error
);
6660 if (!is_ok (error
)) {
6664 mono_array_setref (names
, n
, str
);
6674 #endif /* !HOST_WIN32 */
6676 ICALL_EXPORT MonoArray
*
6677 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6680 MonoArray
*result
= mono_icall_get_environment_variable_names (&error
);
6681 mono_error_set_pending_exception (&error
);
6687 mono_icall_set_environment_variable (MonoString
*name
, MonoString
*value
)
6689 gchar
*utf8_name
, *utf8_value
;
6692 utf8_name
= mono_string_to_utf8_checked (name
, &error
); /* FIXME: this should be ascii */
6693 if (mono_error_set_pending_exception (&error
))
6696 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6697 g_unsetenv (utf8_name
);
6702 utf8_value
= mono_string_to_utf8_checked (value
, &error
);
6703 if (!mono_error_ok (&error
)) {
6705 mono_error_set_pending_exception (&error
);
6708 g_setenv (utf8_name
, utf8_value
, TRUE
);
6711 g_free (utf8_value
);
6713 #endif /* !HOST_WIN32 */
6716 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6718 mono_icall_set_environment_variable (name
, value
);
6722 ves_icall_System_Environment_Exit (int result
)
6724 mono_environment_exitcode_set (result
);
6726 if (!mono_runtime_try_shutdown ())
6727 mono_thread_exit ();
6729 /* Suspend all managed threads since the runtime is going away */
6730 mono_thread_suspend_all_other_threads ();
6732 mono_runtime_quit ();
6734 /* we may need to do some cleanup here... */
6738 ICALL_EXPORT MonoStringHandle
6739 ves_icall_System_Environment_GetGacPath (MonoError
*error
)
6741 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error
);
6745 static inline MonoStringHandle
6746 mono_icall_get_windows_folder_path (int folder
, MonoError
*error
)
6749 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6750 return mono_string_new_handle (mono_domain_get (), "", error
);
6752 #endif /* !HOST_WIN32 */
6754 ICALL_EXPORT MonoStringHandle
6755 ves_icall_System_Environment_GetWindowsFolderPath (int folder
, MonoError
*error
)
6757 return mono_icall_get_windows_folder_path (folder
, error
);
6760 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6762 mono_icall_get_logical_drives (void)
6765 gunichar2 buf
[256], *ptr
, *dname
;
6767 guint initial_size
= 127, size
= 128;
6770 MonoString
*drivestr
;
6771 MonoDomain
*domain
= mono_domain_get ();
6777 while (size
> initial_size
) {
6778 size
= (guint
) mono_w32file_get_logical_drive (initial_size
, ptr
);
6779 if (size
> initial_size
) {
6782 ptr
= (gunichar2
*)g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6783 initial_size
= size
;
6797 result
= mono_array_new_checked (domain
, mono_defaults
.string_class
, ndrives
, &error
);
6798 if (mono_error_set_pending_exception (&error
))
6805 while (*u16
) { u16
++; len
++; }
6806 drivestr
= mono_string_new_utf16_checked (domain
, dname
, len
, &error
);
6807 if (mono_error_set_pending_exception (&error
))
6810 mono_array_setref (result
, ndrives
++, drivestr
);
6820 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6822 ICALL_EXPORT MonoArray
*
6823 ves_icall_System_Environment_GetLogicalDrives (void)
6825 return mono_icall_get_logical_drives ();
6828 ICALL_EXPORT MonoString
*
6829 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString
*path
)
6832 gunichar2 volume_name
[MAX_PATH
+ 1];
6834 if (mono_w32file_get_volume_information (mono_string_chars (path
), NULL
, 0, NULL
, NULL
, NULL
, volume_name
, MAX_PATH
+ 1) == FALSE
)
6836 MonoString
*result
= mono_string_from_utf16_checked (volume_name
, &error
);
6837 mono_error_set_pending_exception (&error
);
6841 ICALL_EXPORT MonoStringHandle
6842 ves_icall_System_Environment_InternalGetHome (MonoError
*error
)
6844 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error
);
6847 static const char *encodings
[] = {
6849 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6850 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6851 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6853 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6854 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6855 "x_unicode_2_0_utf_7",
6857 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6858 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6860 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6863 "unicodefffe", "utf_16be",
6870 * Returns the internal codepage, if the value of "int_code_page" is
6871 * 1 at entry, and we can not compute a suitable code page number,
6872 * returns the code page as a string
6874 ICALL_EXPORT MonoStringHandle
6875 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32
*int_code_page
, MonoError
*error
)
6881 char *codepage
= NULL
;
6883 int want_name
= *int_code_page
;
6886 *int_code_page
= -1;
6888 g_get_charset (&cset
);
6889 c
= codepage
= g_strdup (cset
);
6890 for (c
= codepage
; *c
; c
++){
6891 if (isascii (*c
) && isalpha (*c
))
6896 /* g_print ("charset: %s\n", cset); */
6898 /* handle some common aliases */
6901 for (i
= 0; p
!= 0; ){
6904 p
= encodings
[++i
];
6907 if (strcmp (p
, codepage
) == 0){
6908 *int_code_page
= code
;
6911 p
= encodings
[++i
];
6914 if (strstr (codepage
, "utf_8") != NULL
)
6915 *int_code_page
|= 0x10000000;
6918 if (want_name
&& *int_code_page
== -1)
6919 return mono_string_new_handle (mono_domain_get (), cset
, error
);
6921 return MONO_HANDLE_CAST (MonoString
, NULL_HANDLE
);
6924 ICALL_EXPORT MonoBoolean
6925 ves_icall_System_Environment_get_HasShutdownStarted (void)
6927 if (mono_runtime_is_shutting_down ())
6930 if (mono_domain_is_unloading (mono_domain_get ()))
6937 static inline MonoBoolean
6938 mono_icall_broadcast_setting_change (MonoError
*error
)
6943 #endif /* !HOST_WIN32 */
6946 ves_icall_System_Environment_BroadcastSettingChange (MonoError
*error
)
6949 mono_icall_broadcast_setting_change (error
);
6954 ves_icall_System_Environment_get_TickCount (void)
6956 /* this will overflow after ~24 days */
6957 return (gint32
) (mono_msec_boottime () & 0xffffffff);
6961 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6966 #ifndef DISABLE_REMOTING
6967 ICALL_EXPORT MonoBoolean
6968 ves_icall_IsTransparentProxy (MonoObjectHandle proxy
, MonoError
*error
)
6971 if (MONO_HANDLE_IS_NULL (proxy
))
6974 if (mono_class_is_transparent_proxy (mono_handle_class (proxy
)))
6980 ICALL_EXPORT MonoReflectionMethodHandle
6981 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6982 MonoReflectionTypeHandle rtype
, MonoReflectionMethodHandle rmethod
, MonoError
*error
)
6984 MonoReflectionMethodHandle ret
= MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
);
6987 if (MONO_HANDLE_IS_NULL (rtype
)) {
6988 mono_error_set_argument_null (error
, "type", "");
6991 if (MONO_HANDLE_IS_NULL (rmethod
)) {
6992 mono_error_set_argument_null (error
, "method", "");
6996 MonoMethod
*method
= MONO_HANDLE_GETVAL (rmethod
, method
);
6997 MonoType
*type
= MONO_HANDLE_GETVAL (rtype
, type
);
6998 MonoClass
*klass
= mono_class_from_mono_type (type
);
6999 mono_class_init_checked (klass
, error
);
7000 return_val_if_nok (error
, ret
);
7002 if (MONO_CLASS_IS_INTERFACE (klass
))
7005 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
7008 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
7009 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
7014 mono_class_setup_vtable (klass
);
7015 MonoMethod
**vtable
= klass
->vtable
;
7017 MonoMethod
*res
= NULL
;
7018 if (mono_class_is_interface (method
->klass
)) {
7019 gboolean variance_used
= FALSE
;
7020 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
7021 int offs
= mono_class_interface_offset_with_variance (klass
, method
->klass
, &variance_used
);
7023 res
= vtable
[offs
+ method
->slot
];
7025 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
7028 if (method
->slot
!= -1)
7029 res
= vtable
[method
->slot
];
7035 ret
= mono_method_get_object_handle (mono_domain_get (), res
, NULL
, error
);
7040 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionTypeHandle type
, MonoBoolean enable
, MonoError
*error
)
7044 MonoClass
*klass
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (type
, type
));
7045 MonoVTable
*vtable
= mono_class_vtable_full (mono_domain_get (), klass
, error
);
7046 return_if_nok (error
);
7048 mono_vtable_set_is_remote (vtable
, enable
);
7051 #else /* DISABLE_REMOTING */
7054 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionTypeHandle type
, MonoBoolean enable
, MonoError
*error
)
7057 g_assert_not_reached ();
7062 ICALL_EXPORT MonoObjectHandle
7063 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionTypeHandle type
, MonoError
*error
)
7067 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (type
);
7068 MonoClass
*klass
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (type
, type
));
7069 mono_class_init_checked (klass
, error
);
7070 return_val_if_nok (error
, NULL_HANDLE
);
7072 if (MONO_CLASS_IS_INTERFACE (klass
) || mono_class_is_abstract (klass
)) {
7073 mono_error_set_argument (error
, "type", "Type cannot be instantiated");
7077 if (klass
->rank
>= 1) {
7078 g_assert (klass
->rank
== 1);
7079 return MONO_HANDLE_CAST (MonoObject
, mono_array_new_handle (domain
, klass
->element_class
, 0, error
));
7081 MonoVTable
*vtable
= mono_class_vtable_full (domain
, klass
, error
);
7082 return_val_if_nok (error
, NULL_HANDLE
);
7084 /* Bypass remoting object creation check */
7085 return MONO_HANDLE_NEW (MonoObject
, mono_object_new_alloc_specific_checked (vtable
, error
));
7089 ICALL_EXPORT MonoStringHandle
7090 ves_icall_System_IO_get_temp_path (MonoError
*error
)
7092 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error
);
7095 #ifndef PLATFORM_NO_DRIVEINFO
7096 ICALL_EXPORT MonoBoolean
7097 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString
*path_name
, guint64
*free_bytes_avail
,
7098 guint64
*total_number_of_bytes
, guint64
*total_number_of_free_bytes
,
7103 *error
= ERROR_SUCCESS
;
7105 result
= mono_w32file_get_disk_free_space (mono_string_chars (path_name
), free_bytes_avail
, total_number_of_bytes
, total_number_of_free_bytes
);
7107 *error
= mono_w32error_get_last ();
7112 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7113 static inline guint32
7114 mono_icall_drive_info_get_drive_type (MonoString
*root_path_name
)
7116 return mono_w32file_get_drive_type (mono_string_chars (root_path_name
));
7118 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7120 ICALL_EXPORT guint32
7121 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString
*root_path_name
)
7123 return mono_icall_drive_info_get_drive_type (root_path_name
);
7126 #endif /* PLATFORM_NO_DRIVEINFO */
7128 ICALL_EXPORT gpointer
7129 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod
*method
, MonoError
*error
)
7132 return mono_compile_method_checked (method
, error
);
7135 ICALL_EXPORT MonoStringHandle
7136 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (MonoError
*error
)
7141 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
7143 mono_icall_make_platform_path (path
);
7145 MonoStringHandle mcpath
= mono_string_new_handle (mono_domain_get (), path
, error
);
7148 mono_error_assert_ok (error
);
7153 static MonoStringHandle
7154 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_app_config (MonoError
*error
)
7157 const gchar
*app_config
;
7159 gchar
*config_file_name
, *config_file_path
;
7160 gsize len
, config_file_path_length
, config_ext_length
;
7163 domain
= mono_domain_get ();
7164 MonoStringHandle file
= MONO_HANDLE_NEW (MonoString
, domain
->setup
->configuration_file
);
7165 if (MONO_HANDLE_IS_NULL (file
) || MONO_HANDLE_GETVAL (file
, length
) == 0)
7168 // Retrieve config file and remove the extension
7169 config_file_name
= mono_string_handle_to_utf8 (file
, error
);
7170 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoString
, NULL_HANDLE
));
7172 config_file_path
= mono_portability_find_file (config_file_name
, TRUE
);
7173 if (!config_file_path
)
7174 config_file_path
= config_file_name
;
7176 config_file_path_length
= strlen (config_file_path
);
7177 config_ext_length
= strlen (".config");
7178 if (config_file_path_length
<= config_ext_length
) {
7179 if (config_file_name
!= config_file_path
)
7180 g_free (config_file_name
);
7181 return MONO_HANDLE_CAST (MonoString
, NULL_HANDLE
);
7184 len
= config_file_path_length
- config_ext_length
;
7185 module
= (gchar
*)g_malloc0 (len
+ 1);
7186 memcpy (module
, config_file_path
, len
);
7187 // Get the config file from the module name
7188 app_config
= mono_config_string_for_assembly_file (module
);
7191 if (config_file_name
!= config_file_path
)
7192 g_free (config_file_name
);
7193 g_free (config_file_path
);
7196 return MONO_HANDLE_CAST (MonoString
, NULL_HANDLE
);
7198 return mono_string_new_handle (mono_domain_get (), app_config
, error
);
7201 static MonoStringHandle
7202 get_bundled_machine_config (MonoError
*error
)
7204 const gchar
*machine_config
;
7206 machine_config
= mono_get_machine_config ();
7208 if (!machine_config
)
7209 return NULL_HANDLE_STRING
;
7211 return mono_string_new_handle (mono_domain_get (), machine_config
, error
);
7214 ICALL_EXPORT MonoStringHandle
7215 ves_icall_System_Environment_get_bundled_machine_config (MonoError
*error
)
7217 return get_bundled_machine_config (error
);
7221 ICALL_EXPORT MonoStringHandle
7222 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError
*error
)
7224 return get_bundled_machine_config (error
);
7227 ICALL_EXPORT MonoStringHandle
7228 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError
*error
)
7230 return get_bundled_machine_config (error
);
7234 ICALL_EXPORT MonoStringHandle
7235 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (MonoError
*error
)
7240 path
= g_path_get_dirname (mono_get_config_dir ());
7242 mono_icall_make_platform_path (path
);
7244 MonoStringHandle ipath
= mono_string_new_handle (mono_domain_get (), path
, error
);
7250 ICALL_EXPORT gboolean
7251 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly
, gpointer
*result
, gint32
*size
, MonoError
*error
)
7254 MonoPEResourceDataEntry
*entry
;
7257 if (!assembly
|| !result
|| !size
)
7262 MonoAssembly
*assm
= MONO_HANDLE_GETVAL (assembly
, assembly
);
7263 image
= assm
->image
;
7264 entry
= (MonoPEResourceDataEntry
*)mono_image_lookup_resource (image
, MONO_PE_RESOURCE_ID_ASPNET_STRING
, 0, NULL
);
7268 *result
= mono_image_rva_map (image
, entry
->rde_data_offset
);
7273 *size
= entry
->rde_size
;
7278 ICALL_EXPORT MonoBoolean
7279 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7281 return mono_is_debugger_attached ();
7284 ICALL_EXPORT MonoBoolean
7285 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7287 if (mono_get_runtime_callbacks ()->debug_log_is_enabled
)
7288 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7294 ves_icall_System_Diagnostics_Debugger_Log (int level
, MonoString
*category
, MonoString
*message
)
7296 if (mono_get_runtime_callbacks ()->debug_log
)
7297 mono_get_runtime_callbacks ()->debug_log (level
, category
, message
);
7302 mono_icall_write_windows_debug_string (MonoString
*message
)
7304 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7306 #endif /* !HOST_WIN32 */
7309 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
7311 mono_icall_write_windows_debug_string (message
);
7314 /* Only used for value types */
7315 ICALL_EXPORT MonoObjectHandle
7316 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionTypeHandle ref_type
, MonoError
*error
)
7319 MonoDomain
*domain
= MONO_HANDLE_DOMAIN (ref_type
);
7320 MonoType
*type
= MONO_HANDLE_GETVAL (ref_type
, type
);
7321 MonoClass
*klass
= mono_class_from_mono_type (type
);
7323 mono_class_init_checked (klass
, error
);
7327 if (mono_class_is_nullable (klass
))
7328 /* No arguments -> null */
7331 return MONO_HANDLE_NEW (MonoObject
, mono_object_new_checked (domain
, klass
, error
));
7334 ICALL_EXPORT MonoReflectionMethodHandle
7335 ves_icall_MonoMethod_get_base_method (MonoReflectionMethodHandle m
, gboolean definition
, MonoError
*error
)
7338 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
7340 MonoMethod
*base
= mono_method_get_base_method (method
, definition
, error
);
7341 return_val_if_nok (error
, MONO_HANDLE_CAST (MonoReflectionMethod
, NULL_HANDLE
));
7342 if (base
== method
) {
7343 /* we want to short-circuit and return 'm' here. But we should
7344 return the same method object that
7345 mono_method_get_object_handle, below would return. Since
7346 that call takes NULL for the reftype argument, it will take
7347 base->klass as the reflected type for the MonoMethod. So we
7348 need to check that m also has base->klass as the reflected
7350 MonoReflectionTypeHandle orig_reftype
= MONO_HANDLE_NEW_GET (MonoReflectionType
, m
, reftype
);
7351 MonoClass
*orig_klass
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (orig_reftype
, type
));
7352 if (base
->klass
== orig_klass
)
7355 return mono_method_get_object_handle (mono_domain_get (), base
, NULL
, error
);
7358 ICALL_EXPORT MonoStringHandle
7359 ves_icall_MonoMethod_get_name (MonoReflectionMethodHandle m
, MonoError
*error
)
7362 MonoMethod
*method
= MONO_HANDLE_GETVAL (m
, method
);
7364 MonoStringHandle s
= mono_string_new_handle (MONO_HANDLE_DOMAIN (m
), method
->name
, error
);
7366 return NULL_HANDLE_STRING
;
7367 MONO_HANDLE_SET (m
, name
, s
);
7372 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
7374 iter
->sig
= *(MonoMethodSignature
**)argsp
;
7376 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
7377 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
7380 /* FIXME: it's not documented what start is exactly... */
7384 iter
->args
= argsp
+ sizeof (gpointer
);
7386 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
7388 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7391 ICALL_EXPORT MonoTypedRef
7392 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
7394 guint32 i
, arg_size
;
7398 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7400 g_assert (i
< iter
->sig
->param_count
);
7402 res
.type
= iter
->sig
->params
[i
];
7403 res
.klass
= mono_class_from_mono_type (res
.type
);
7404 arg_size
= mono_type_stack_size (res
.type
, &align
);
7405 #if defined(__arm__) || defined(__mips__)
7406 iter
->args
= (guint8
*)(((gsize
)iter
->args
+ (align
) - 1) & ~(align
- 1));
7408 res
.value
= iter
->args
;
7409 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7410 if (arg_size
<= sizeof (gpointer
)) {
7412 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
7413 res
.value
= (guint8
*)res
.value
+ padding
;
7416 iter
->args
= (char*)iter
->args
+ arg_size
;
7419 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7424 ICALL_EXPORT MonoTypedRef
7425 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
7427 guint32 i
, arg_size
;
7431 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7433 g_assert (i
< iter
->sig
->param_count
);
7435 while (i
< iter
->sig
->param_count
) {
7436 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
7438 res
.type
= iter
->sig
->params
[i
];
7439 res
.klass
= mono_class_from_mono_type (res
.type
);
7440 /* FIXME: endianess issue... */
7441 arg_size
= mono_type_stack_size (res
.type
, &align
);
7442 #if defined(__arm__) || defined(__mips__)
7443 iter
->args
= (guint8
*)(((gsize
)iter
->args
+ (align
) - 1) & ~(align
- 1));
7445 res
.value
= iter
->args
;
7446 iter
->args
= (char*)iter
->args
+ arg_size
;
7448 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7451 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7459 ICALL_EXPORT MonoType
*
7460 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7464 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7466 g_assert (i
< iter
->sig
->param_count
);
7468 return iter
->sig
->params
[i
];
7471 ICALL_EXPORT MonoObject
*
7472 mono_TypedReference_ToObject (MonoTypedRef
* tref
)
7475 MonoObject
*result
= NULL
;
7476 if (MONO_TYPE_IS_REFERENCE (tref
->type
)) {
7477 MonoObject
** objp
= (MonoObject
**)tref
->value
;
7481 result
= mono_value_box_checked (mono_domain_get (), tref
->klass
, tref
->value
, &error
);
7482 mono_error_set_pending_exception (&error
);
7486 ICALL_EXPORT MonoTypedRef
7487 mono_TypedReference_MakeTypedReferenceInternal (MonoObject
*target
, MonoArray
*fields
)
7490 MonoReflectionField
*f
;
7492 MonoType
*ftype
= NULL
;
7496 memset (&res
, 0, sizeof (res
));
7499 g_assert (mono_array_length (fields
) > 0);
7501 klass
= target
->vtable
->klass
;
7503 for (i
= 0; i
< mono_array_length (fields
); ++i
) {
7504 f
= mono_array_get (fields
, MonoReflectionField
*, i
);
7506 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7509 if (f
->field
->parent
!= klass
) {
7510 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7514 p
= (guint8
*)target
+ f
->field
->offset
;
7516 p
+= f
->field
->offset
- sizeof (MonoObject
);
7517 klass
= mono_class_from_mono_type (f
->field
->type
);
7518 ftype
= f
->field
->type
;
7522 res
.klass
= mono_class_from_mono_type (ftype
);
7529 prelink_method (MonoMethod
*method
, MonoError
*error
)
7531 const char *exc_class
, *exc_arg
;
7534 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7536 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7538 mono_error_set_generic_error (error
, "System", exc_class
, "%s", exc_arg
);
7541 /* create the wrapper, too? */
7545 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethodHandle method
, MonoError
*error
)
7549 prelink_method (MONO_HANDLE_GETVAL (method
, method
), error
);
7553 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionTypeHandle type
, MonoError
*error
)
7556 MonoClass
*klass
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (type
, type
));
7558 gpointer iter
= NULL
;
7560 mono_class_init_checked (klass
, error
);
7561 return_if_nok (error
);
7563 while ((m
= mono_class_get_methods (klass
, &iter
))) {
7564 prelink_method (m
, error
);
7565 return_if_nok (error
);
7569 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7571 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7572 gint32
const **exponents
,
7573 gunichar2
const **digitLowerTable
,
7574 gunichar2
const **digitUpperTable
,
7575 gint64
const **tenPowersList
,
7576 gint32
const **decHexDigits
)
7578 *mantissas
= Formatter_MantissaBitsTable
;
7579 *exponents
= Formatter_TensExponentTable
;
7580 *digitLowerTable
= Formatter_DigitLowerTable
;
7581 *digitUpperTable
= Formatter_DigitUpperTable
;
7582 *tenPowersList
= Formatter_TenPowersList
;
7583 *decHexDigits
= Formatter_DecHexDigits
;
7587 add_modifier_to_array (MonoDomain
*domain
, MonoImage
*image
, MonoCustomMod
*modifier
, MonoArrayHandle dest
, int dest_idx
, MonoError
*error
)
7589 HANDLE_FUNCTION_ENTER ();
7591 MonoClass
*klass
= mono_class_get_checked (image
, modifier
->token
, error
);
7595 MonoReflectionTypeHandle rt
= mono_type_get_object_handle (domain
, &klass
->byval_arg
, error
);
7599 MONO_HANDLE_ARRAY_SETREF (dest
, dest_idx
, rt
);
7601 HANDLE_FUNCTION_RETURN_VAL (is_ok (error
));
7605 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7606 * and avoid useless allocations.
7608 static MonoArrayHandle
7609 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
, MonoError
*error
)
7612 MonoDomain
*domain
= mono_domain_get ();
7615 for (i
= 0; i
< type
->num_mods
; ++i
) {
7616 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7620 return MONO_HANDLE_NEW (MonoArray
, NULL
);
7622 MonoArrayHandle res
= mono_array_new_handle (domain
, mono_defaults
.systemtype_class
, count
, error
);
7626 for (i
= 0; i
< type
->num_mods
; ++i
) {
7627 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7628 if (!add_modifier_to_array (domain
, image
, &type
->modifiers
[i
], res
, count
, error
))
7635 return MONO_HANDLE_NEW (MonoArray
, NULL
);
7638 ICALL_EXPORT MonoArrayHandle
7639 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameterHandle param
, MonoBoolean optional
, MonoError
*error
)
7642 MonoReflectionTypeHandle rt
= MONO_HANDLE_NEW (MonoReflectionType
, NULL
);
7643 MONO_HANDLE_GET (rt
, param
, ClassImpl
);
7644 MonoType
*type
= MONO_HANDLE_GETVAL (rt
, type
);
7645 MonoObjectHandle member
= MONO_HANDLE_NEW (MonoObject
, NULL
);
7646 MONO_HANDLE_GET (member
, param
, MemberImpl
);
7647 MonoClass
*member_class
= mono_handle_class (member
);
7648 MonoMethod
*method
= NULL
;
7651 MonoMethodSignature
*sig
;
7653 if (mono_class_is_reflection_method_or_constructor (member_class
)) {
7654 method
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod
, member
), method
);
7655 } else if (member_class
->image
== mono_defaults
.corlib
&& !strcmp ("MonoProperty", member_class
->name
)) {
7656 MonoProperty
*prop
= MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionProperty
, member
), property
);
7657 if (!(method
= prop
->get
))
7661 char *type_name
= mono_type_get_full_name (member_class
);
7662 mono_error_set_not_supported (error
, "Custom modifiers on a ParamInfo with member %s are not supported", type_name
);
7664 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
7667 image
= method
->klass
->image
;
7668 pos
= MONO_HANDLE_GETVAL (param
, PositionImpl
);
7669 sig
= mono_method_signature (method
);
7673 type
= sig
->params
[pos
];
7675 return type_array_from_modifiers (image
, type
, optional
, error
);
7679 get_property_type (MonoProperty
*prop
)
7681 MonoMethodSignature
*sig
;
7683 sig
= mono_method_signature (prop
->get
);
7685 } else if (prop
->set
) {
7686 sig
= mono_method_signature (prop
->set
);
7687 return sig
->params
[sig
->param_count
- 1];
7692 ICALL_EXPORT MonoArrayHandle
7693 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property
, MonoBoolean optional
, MonoError
*error
)
7696 MonoProperty
*prop
= MONO_HANDLE_GETVAL (property
, property
);
7697 MonoClass
*klass
= MONO_HANDLE_GETVAL (property
, klass
);
7698 MonoType
*type
= get_property_type (prop
);
7699 MonoImage
*image
= klass
->image
;
7702 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
7703 return type_array_from_modifiers (image
, type
, optional
, error
);
7707 *Construct a MonoType suited to be used to decode a constant blob object.
7709 * @type is the target type which will be constructed
7710 * @blob_type is the blob type, for example, that comes from the constant table
7711 * @real_type is the expected constructed type.
7714 mono_type_from_blob_type (MonoType
*type
, MonoTypeEnum blob_type
, MonoType
*real_type
)
7716 type
->type
= blob_type
;
7717 type
->data
.klass
= NULL
;
7718 if (blob_type
== MONO_TYPE_CLASS
)
7719 type
->data
.klass
= mono_defaults
.object_class
;
7720 else if (real_type
->type
== MONO_TYPE_VALUETYPE
&& real_type
->data
.klass
->enumtype
) {
7721 /* For enums, we need to use the base type */
7722 type
->type
= MONO_TYPE_VALUETYPE
;
7723 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7725 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7728 ICALL_EXPORT MonoObject
*
7729 property_info_get_default_value (MonoReflectionProperty
*property
)
7733 MonoProperty
*prop
= property
->property
;
7734 MonoType
*type
= get_property_type (prop
);
7735 MonoDomain
*domain
= mono_object_domain (property
);
7736 MonoTypeEnum def_type
;
7737 const char *def_value
;
7740 mono_class_init (prop
->parent
);
7742 if (!(prop
->attrs
& PROPERTY_ATTRIBUTE_HAS_DEFAULT
)) {
7743 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL
));
7747 def_value
= mono_class_get_property_default_value (prop
, &def_type
);
7749 mono_type_from_blob_type (&blob_type
, def_type
, type
);
7750 o
= mono_get_object_from_blob (domain
, &blob_type
, def_value
, &error
);
7752 mono_error_set_pending_exception (&error
);
7756 ICALL_EXPORT MonoBoolean
7757 ves_icall_MonoCustomAttrs_IsDefinedInternal (MonoObjectHandle obj
, MonoReflectionTypeHandle attr_type
, MonoError
*error
)
7760 MonoClass
*attr_class
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (attr_type
, type
));
7762 mono_class_init_checked (attr_class
, error
);
7763 return_val_if_nok (error
, FALSE
);
7765 MonoCustomAttrInfo
*cinfo
= mono_reflection_get_custom_attrs_info_checked (obj
, error
);
7766 return_val_if_nok (error
, FALSE
);
7770 gboolean found
= mono_custom_attrs_has_attr (cinfo
, attr_class
);
7772 mono_custom_attrs_free (cinfo
);
7776 ICALL_EXPORT MonoArrayHandle
7777 ves_icall_MonoCustomAttrs_GetCustomAttributesInternal (MonoObjectHandle obj
, MonoReflectionTypeHandle attr_type
, mono_bool pseudoattrs
, MonoError
*error
)
7779 MonoClass
*attr_class
;
7780 if (MONO_HANDLE_IS_NULL (attr_type
))
7783 attr_class
= mono_class_from_mono_type (MONO_HANDLE_GETVAL (attr_type
, type
));
7786 mono_class_init_checked (attr_class
, error
);
7788 return MONO_HANDLE_CAST (MonoArray
, NULL_HANDLE
);
7791 return mono_reflection_get_custom_attrs_by_type_handle (obj
, attr_class
, error
);
7794 ICALL_EXPORT MonoArrayHandle
7795 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObjectHandle obj
, MonoError
*error
)
7798 return mono_reflection_get_custom_attrs_data_checked (obj
, error
);
7802 ICALL_EXPORT MonoStringHandle
7803 ves_icall_Mono_Runtime_GetDisplayName (MonoError
*error
)
7806 MonoStringHandle display_name
;
7809 info
= mono_get_runtime_callbacks ()->get_runtime_build_info ();
7810 display_name
= mono_string_new_handle (mono_domain_get (), info
, error
);
7812 return display_name
;
7816 static inline gint32
7817 mono_icall_wait_for_input_idle (gpointer handle
, gint32 milliseconds
)
7819 return WAIT_TIMEOUT
;
7821 #endif /* !HOST_WIN32 */
7824 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle
, gint32 milliseconds
)
7826 return mono_icall_wait_for_input_idle (handle
, milliseconds
);
7830 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7832 return mono_process_current_pid ();
7835 ICALL_EXPORT MonoBoolean
7836 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7848 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException
* ex
)
7850 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7854 ICALL_EXPORT MonoObject
*
7855 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject
* type
)
7857 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7862 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject
* obj
)
7864 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7868 ICALL_EXPORT MonoObject
*
7869 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7871 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7875 ICALL_EXPORT MonoBoolean
7876 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error
, MonoString
* message
, void* languageException
)
7878 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7883 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject
* error
)
7885 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7889 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString
* sourceString
, int length
, void** hstring
)
7891 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7896 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring
)
7898 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7902 ICALL_EXPORT mono_unichar2
*
7903 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring
, unsigned* length
)
7905 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7912 #ifndef DISABLE_ICALL_TABLES
7914 #define ICALL_TYPE(id,name,first)
7915 #define ICALL(id,name,func) Icall_ ## id,
7916 #define HANDLES(inner) inner
7919 #include "metadata/icall-def.h"
7925 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7926 #define ICALL(id,name,func)
7928 #define HANDLES(inner) inner
7930 #include "metadata/icall-def.h"
7936 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7937 #define ICALL(id,name,func)
7939 #define HANDLES(inner) inner
7941 guint16 first_icall
;
7944 static const IcallTypeDesc
7945 icall_type_descs
[] = {
7946 #include "metadata/icall-def.h"
7950 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7953 #define HANDLES(inner) inner
7955 #define ICALL_TYPE(id,name,first)
7958 #ifdef HAVE_ARRAY_ELEM_INIT
7959 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7960 #define MSGSTRFIELD1(line) str##line
7962 static const struct msgstrtn_t
{
7963 #define ICALL(id,name,func)
7965 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7966 #include "metadata/icall-def.h"
7968 } icall_type_names_str
= {
7969 #define ICALL_TYPE(id,name,first) (name),
7970 #include "metadata/icall-def.h"
7973 static const guint16 icall_type_names_idx
[] = {
7974 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7975 #include "metadata/icall-def.h"
7978 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7980 static const struct msgstr_t
{
7982 #define ICALL_TYPE(id,name,first)
7983 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7984 #include "metadata/icall-def.h"
7986 } icall_names_str
= {
7987 #define ICALL(id,name,func) (name),
7988 #include "metadata/icall-def.h"
7991 static const guint16 icall_names_idx
[] = {
7992 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7993 #include "metadata/icall-def.h"
7996 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8002 #define ICALL_TYPE(id,name,first) name,
8003 #define ICALL(id,name,func)
8004 static const char* const
8005 icall_type_names
[] = {
8006 #include "metadata/icall-def.h"
8010 #define icall_type_name_get(id) (icall_type_names [(id)])
8014 #define ICALL_TYPE(id,name,first)
8015 #define ICALL(id,name,func) name,
8016 static const char* const
8018 #include "metadata/icall-def.h"
8021 #define icall_name_get(id) icall_names [(id)]
8023 #endif /* !HAVE_ARRAY_ELEM_INIT */
8026 #define HANDLES(inner) inner
8029 #define ICALL_TYPE(id,name,first)
8030 #define ICALL(id,name,func) func,
8031 static const gconstpointer
8032 icall_functions
[] = {
8033 #include "metadata/icall-def.h"
8037 #ifdef ENABLE_ICALL_SYMBOL_MAP
8039 #define HANDLES(inner) inner
8042 #define ICALL_TYPE(id,name,first)
8043 #define ICALL(id,name,func) #func,
8044 static const gconstpointer
8045 icall_symbols
[] = {
8046 #include "metadata/icall-def.h"
8053 #define ICALL_TYPE(id,name,first)
8054 #define ICALL(id,name,func) 0,
8056 #define HANDLES(inner) 1,
8058 icall_uses_handles
[] = {
8059 #include "metadata/icall-def.h"
8064 #endif /* DISABLE_ICALL_TABLES */
8066 static mono_mutex_t icall_mutex
;
8067 static GHashTable
*icall_hash
= NULL
;
8068 static GHashTable
*jit_icall_hash_name
= NULL
;
8069 static GHashTable
*jit_icall_hash_addr
= NULL
;
8072 mono_icall_init (void)
8074 #ifndef DISABLE_ICALL_TABLES
8077 /* check that tables are sorted: disable in release */
8080 const char *prev_class
= NULL
;
8081 const char *prev_method
;
8083 for (i
= 0; i
< Icall_type_num
; ++i
) {
8084 const IcallTypeDesc
*desc
;
8087 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
8088 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
8089 prev_class
= icall_type_name_get (i
);
8090 desc
= &icall_type_descs
[i
];
8091 num_icalls
= icall_desc_num_icalls (desc
);
8092 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8093 for (j
= 0; j
< num_icalls
; ++j
) {
8094 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
8095 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
8096 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
8097 prev_method
= methodn
;
8103 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
8104 mono_os_mutex_init (&icall_mutex
);
8108 mono_icall_lock (void)
8110 mono_locks_os_acquire (&icall_mutex
, IcallLock
);
8114 mono_icall_unlock (void)
8116 mono_locks_os_release (&icall_mutex
, IcallLock
);
8120 mono_icall_cleanup (void)
8122 g_hash_table_destroy (icall_hash
);
8123 g_hash_table_destroy (jit_icall_hash_name
);
8124 g_hash_table_destroy (jit_icall_hash_addr
);
8125 mono_os_mutex_destroy (&icall_mutex
);
8129 * mono_add_internal_call:
8130 * \param name method specification to surface to the managed world
8131 * \param method pointer to a C method to invoke when the method is called
8133 * This method surfaces the C function pointed by \p method as a method
8134 * that has been surfaced in managed code with the method specified in
8135 * \p name as an internal call.
8137 * Internal calls are surfaced to all app domains loaded and they are
8138 * accessibly by a type with the specified name.
8140 * You must provide a fully qualified type name, that is namespaces
8141 * and type name, followed by a colon and the method name, with an
8142 * optional signature to bind.
8144 * For example, the following are all valid declarations:
8146 * \c MyApp.Services.ScriptService:Accelerate
8148 * \c MyApp.Services.ScriptService:Slowdown(int,bool)
8150 * You use method parameters in cases where there might be more than
8151 * one surface method to managed code. That way you can register different
8152 * internal calls for different method overloads.
8154 * The internal calls are invoked with no marshalling. This means that .NET
8155 * types like \c System.String are exposed as \c MonoString* parameters. This is
8156 * different than the way that strings are surfaced in P/Invoke.
8158 * For more information on how the parameters are marshalled, see the
8159 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8162 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8163 * reference for more information on the format of method descriptions.
8166 mono_add_internal_call (const char *name
, gconstpointer method
)
8170 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
8172 mono_icall_unlock ();
8175 #ifndef DISABLE_ICALL_TABLES
8177 #ifdef HAVE_ARRAY_ELEM_INIT
8179 compare_method_imap (const void *key
, const void *elem
)
8181 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
8182 return strcmp (key
, method_name
);
8186 find_slot_icall (const IcallTypeDesc
*imap
, const char *name
)
8188 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
);
8191 return (nameslot
- &icall_names_idx
[0]);
8195 find_uses_handles_icall (const IcallTypeDesc
*imap
, const char *name
)
8197 gsize slotnum
= find_slot_icall (imap
, name
);
8200 return (gboolean
)icall_uses_handles
[slotnum
];
8204 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
8206 gsize slotnum
= find_slot_icall (imap
, name
);
8209 return (gpointer
)icall_functions
[slotnum
];
8213 compare_class_imap (const void *key
, const void *elem
)
8215 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
8216 return strcmp (key
, class_name
);
8219 static const IcallTypeDesc
*
8220 find_class_icalls (const char *name
)
8222 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
);
8225 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
8228 #else /* HAVE_ARRAY_ELEM_INIT */
8231 compare_method_imap (const void *key
, const void *elem
)
8233 const char** method_name
= (const char**)elem
;
8234 return strcmp (key
, *method_name
);
8238 find_slot_icall (const IcallTypeDesc
*imap
, const char *name
)
8240 const char **nameslot
= mono_binary_search (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
8243 return nameslot
- icall_names
;
8247 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
8249 gsize slotnum
= find_slot_icall (imap
, name
);
8252 return (gpointer
)icall_functions
[slotnum
];
8256 find_uses_handles_icall (const IcallTypeDesc
*imap
, const char *name
)
8258 gsize slotnum
= find_slot_icall (imap
, name
);
8261 return (gboolean
)icall_uses_handles
[slotnum
];
8265 compare_class_imap (const void *key
, const void *elem
)
8267 const char** class_name
= (const char**)elem
;
8268 return strcmp (key
, *class_name
);
8271 static const IcallTypeDesc
*
8272 find_class_icalls (const char *name
)
8274 const char **nameslot
= mono_binary_search (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
8277 return &icall_type_descs
[nameslot
- icall_type_names
];
8280 #endif /* HAVE_ARRAY_ELEM_INIT */
8282 #endif /* DISABLE_ICALL_TABLES */
8285 * we should probably export this as an helper (handle nested types).
8286 * Returns the number of chars written in buf.
8289 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
8291 int nspacelen
, cnamelen
;
8292 nspacelen
= strlen (klass
->name_space
);
8293 cnamelen
= strlen (klass
->name
);
8294 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
8297 memcpy (buf
, klass
->name_space
, nspacelen
);
8298 buf
[nspacelen
++] = '.';
8300 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
8301 buf
[nspacelen
+ cnamelen
] = 0;
8302 return nspacelen
+ cnamelen
;
8305 #ifdef DISABLE_ICALL_TABLES
8307 no_icall_table (void)
8309 g_assert_not_reached ();
8314 * mono_lookup_internal_call_full:
8315 * \param method the method to look up
8316 * \param uses_handles out argument if method needs handles around managed objects.
8317 * \returns a pointer to the icall code for the given method. If
8318 * \p uses_handles is not NULL, it will be set to TRUE if the method
8319 * needs managed objects wrapped using the infrastructure in handle.h
8321 * If the method is not found, warns and returns NULL.
8324 mono_lookup_internal_call_full (MonoMethod
*method
, mono_bool
*uses_handles
)
8329 int typelen
= 0, mlen
, siglen
;
8331 #ifndef DISABLE_ICALL_TABLES
8332 const IcallTypeDesc
*imap
= NULL
;
8335 g_assert (method
!= NULL
);
8337 if (method
->is_inflated
)
8338 method
= ((MonoMethodInflated
*) method
)->declaring
;
8340 if (method
->klass
->nested_in
) {
8341 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
8345 mname
[pos
++] = '/';
8348 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
8354 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
8359 #ifndef DISABLE_ICALL_TABLES
8360 imap
= find_class_icalls (mname
);
8363 mname
[typelen
] = ':';
8364 mname
[typelen
+ 1] = ':';
8366 mlen
= strlen (method
->name
);
8367 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
8368 sigstart
= mname
+ typelen
+ 2 + mlen
;
8371 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
8372 siglen
= strlen (tmpsig
);
8373 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
8376 memcpy (sigstart
+ 1, tmpsig
, siglen
);
8377 sigstart
[siglen
+ 1] = ')';
8378 sigstart
[siglen
+ 2] = 0;
8383 res
= g_hash_table_lookup (icall_hash
, mname
);
8386 *uses_handles
= FALSE
;
8387 mono_icall_unlock ();;
8390 /* try without signature */
8392 res
= g_hash_table_lookup (icall_hash
, mname
);
8395 *uses_handles
= FALSE
;
8396 mono_icall_unlock ();
8400 #ifdef DISABLE_ICALL_TABLES
8401 mono_icall_unlock ();
8402 /* Fail only when the result is actually used */
8403 /* mono_marshal_get_native_wrapper () depends on this */
8404 if (method
->klass
== mono_defaults
.string_class
&& !strcmp (method
->name
, ".ctor"))
8405 return ves_icall_System_String_ctor_RedirectToCreateString
;
8407 return no_icall_table
;
8409 /* it wasn't found in the static call tables */
8412 *uses_handles
= FALSE
;
8413 mono_icall_unlock ();
8416 res
= find_method_icall (imap
, sigstart
- mlen
);
8419 *uses_handles
= find_uses_handles_icall (imap
, sigstart
- mlen
);
8420 mono_icall_unlock ();
8423 /* try _with_ signature */
8425 res
= find_method_icall (imap
, sigstart
- mlen
);
8428 *uses_handles
= find_uses_handles_icall (imap
, sigstart
- mlen
);
8429 mono_icall_unlock ();
8433 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
8434 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8435 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
8436 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8437 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");
8438 g_print ("If you see other errors or faults after this message they are probably related\n");
8439 g_print ("and you need to fix your mono install first.\n");
8441 mono_icall_unlock ();
8448 * mono_lookup_internal_call:
8451 mono_lookup_internal_call (MonoMethod
*method
)
8453 return mono_lookup_internal_call_full (method
, NULL
);
8456 #ifdef ENABLE_ICALL_SYMBOL_MAP
8458 func_cmp (gconstpointer key
, gconstpointer p
)
8460 return (gsize
)key
- (gsize
)*(gsize
*)p
;
8465 * mono_lookup_icall_symbol:
8467 * Given the icall METHOD, returns its C symbol.
8470 mono_lookup_icall_symbol (MonoMethod
*m
)
8472 #ifdef DISABLE_ICALL_TABLES
8473 g_assert_not_reached ();
8476 #ifdef ENABLE_ICALL_SYMBOL_MAP
8480 static gconstpointer
*functions_sorted
;
8481 static const char**symbols_sorted
;
8482 static gboolean inited
;
8487 functions_sorted
= g_malloc (G_N_ELEMENTS (icall_functions
) * sizeof (gpointer
));
8488 memcpy (functions_sorted
, icall_functions
, G_N_ELEMENTS (icall_functions
) * sizeof (gpointer
));
8489 symbols_sorted
= g_malloc (G_N_ELEMENTS (icall_functions
) * sizeof (gpointer
));
8490 memcpy (symbols_sorted
, icall_symbols
, G_N_ELEMENTS (icall_functions
) * sizeof (gpointer
));
8491 /* Bubble sort the two arrays */
8495 for (i
= 0; i
< G_N_ELEMENTS (icall_functions
) - 1; ++i
) {
8496 if (functions_sorted
[i
] > functions_sorted
[i
+ 1]) {
8499 tmp
= functions_sorted
[i
];
8500 functions_sorted
[i
] = functions_sorted
[i
+ 1];
8501 functions_sorted
[i
+ 1] = tmp
;
8502 tmp
= symbols_sorted
[i
];
8503 symbols_sorted
[i
] = symbols_sorted
[i
+ 1];
8504 symbols_sorted
[i
+ 1] = tmp
;
8511 func
= mono_lookup_internal_call (m
);
8514 slot
= mono_binary_search (func
, functions_sorted
, G_N_ELEMENTS (icall_functions
), sizeof (gpointer
), func_cmp
);
8518 return symbols_sorted
[(gpointer
*)slot
- (gpointer
*)functions_sorted
];
8520 fprintf (stderr
, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8521 g_assert_not_reached ();
8528 type_from_typename (char *type_name
)
8530 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
8532 if (!strcmp (type_name
, "int"))
8533 klass
= mono_defaults
.int_class
;
8534 else if (!strcmp (type_name
, "ptr"))
8535 klass
= mono_defaults
.int_class
;
8536 else if (!strcmp (type_name
, "void"))
8537 klass
= mono_defaults
.void_class
;
8538 else if (!strcmp (type_name
, "int32"))
8539 klass
= mono_defaults
.int32_class
;
8540 else if (!strcmp (type_name
, "uint32"))
8541 klass
= mono_defaults
.uint32_class
;
8542 else if (!strcmp (type_name
, "int8"))
8543 klass
= mono_defaults
.sbyte_class
;
8544 else if (!strcmp (type_name
, "uint8"))
8545 klass
= mono_defaults
.byte_class
;
8546 else if (!strcmp (type_name
, "int16"))
8547 klass
= mono_defaults
.int16_class
;
8548 else if (!strcmp (type_name
, "uint16"))
8549 klass
= mono_defaults
.uint16_class
;
8550 else if (!strcmp (type_name
, "long"))
8551 klass
= mono_defaults
.int64_class
;
8552 else if (!strcmp (type_name
, "ulong"))
8553 klass
= mono_defaults
.uint64_class
;
8554 else if (!strcmp (type_name
, "float"))
8555 klass
= mono_defaults
.single_class
;
8556 else if (!strcmp (type_name
, "double"))
8557 klass
= mono_defaults
.double_class
;
8558 else if (!strcmp (type_name
, "object"))
8559 klass
= mono_defaults
.object_class
;
8560 else if (!strcmp (type_name
, "obj"))
8561 klass
= mono_defaults
.object_class
;
8562 else if (!strcmp (type_name
, "string"))
8563 klass
= mono_defaults
.string_class
;
8564 else if (!strcmp (type_name
, "bool"))
8565 klass
= mono_defaults
.boolean_class
;
8566 else if (!strcmp (type_name
, "boolean"))
8567 klass
= mono_defaults
.boolean_class
;
8569 g_error ("%s", type_name
);
8570 g_assert_not_reached ();
8572 return &klass
->byval_arg
;
8576 * LOCKING: Take the corlib image lock.
8578 MonoMethodSignature
*
8579 mono_create_icall_signature (const char *sigstr
)
8584 MonoMethodSignature
*res
, *res2
;
8585 MonoImage
*corlib
= mono_defaults
.corlib
;
8587 mono_image_lock (corlib
);
8588 res
= (MonoMethodSignature
*)g_hash_table_lookup (corlib
->helper_signatures
, sigstr
);
8589 mono_image_unlock (corlib
);
8594 parts
= g_strsplit (sigstr
, " ", 256);
8603 res
= mono_metadata_signature_alloc (corlib
, len
- 1);
8608 * Under windows, the default pinvoke calling convention is STDCALL but
8611 res
->call_convention
= MONO_CALL_C
;
8614 res
->ret
= type_from_typename (parts
[0]);
8615 for (i
= 1; i
< len
; ++i
) {
8616 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
8621 mono_image_lock (corlib
);
8622 res2
= (MonoMethodSignature
*)g_hash_table_lookup (corlib
->helper_signatures
, sigstr
);
8624 res
= res2
; /*Value is allocated in the image pool*/
8626 g_hash_table_insert (corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
8627 mono_image_unlock (corlib
);
8633 mono_find_jit_icall_by_name (const char *name
)
8635 MonoJitICallInfo
*info
;
8636 g_assert (jit_icall_hash_name
);
8639 info
= (MonoJitICallInfo
*)g_hash_table_lookup (jit_icall_hash_name
, name
);
8640 mono_icall_unlock ();
8645 mono_find_jit_icall_by_addr (gconstpointer addr
)
8647 MonoJitICallInfo
*info
;
8648 g_assert (jit_icall_hash_addr
);
8651 info
= (MonoJitICallInfo
*)g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
8652 mono_icall_unlock ();
8658 * mono_get_jit_icall_info:
8660 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8661 * caller should access it while holding the icall lock.
8664 mono_get_jit_icall_info (void)
8666 return jit_icall_hash_name
;
8670 * mono_lookup_jit_icall_symbol:
8672 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8675 mono_lookup_jit_icall_symbol (const char *name
)
8677 MonoJitICallInfo
*info
;
8678 const char *res
= NULL
;
8681 info
= (MonoJitICallInfo
*)g_hash_table_lookup (jit_icall_hash_name
, name
);
8683 res
= info
->c_symbol
;
8684 mono_icall_unlock ();
8689 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
8692 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
8693 mono_icall_unlock ();
8697 * 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
8698 * icalls without wrappers in some cases.
8701 mono_register_jit_icall_full (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
, gboolean no_raise
, const char *c_symbol
)
8703 MonoJitICallInfo
*info
;
8710 if (!jit_icall_hash_name
) {
8711 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
8712 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
8715 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
8716 g_warning ("jit icall already defined \"%s\"\n", name
);
8717 g_assert_not_reached ();
8720 info
= g_new0 (MonoJitICallInfo
, 1);
8725 info
->c_symbol
= c_symbol
;
8726 info
->no_raise
= no_raise
;
8729 info
->wrapper
= func
;
8731 info
->wrapper
= NULL
;
8734 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
8735 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
8737 mono_icall_unlock ();
8742 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
8744 return mono_register_jit_icall_full (func
, name
, sig
, is_save
, FALSE
, NULL
);