5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
10 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
21 #ifdef HAVE_SYS_TIME_H
27 #if defined (PLATFORM_WIN32)
31 #include "mono/utils/mono-membar.h"
32 #include <mono/metadata/object.h>
33 #include <mono/metadata/threads.h>
34 #include <mono/metadata/threads-types.h>
35 #include <mono/metadata/threadpool.h>
36 #include <mono/metadata/monitor.h>
37 #include <mono/metadata/reflection.h>
38 #include <mono/metadata/assembly.h>
39 #include <mono/metadata/tabledefs.h>
40 #include <mono/metadata/exception.h>
41 #include <mono/metadata/file-io.h>
42 #include <mono/metadata/console-io.h>
43 #include <mono/metadata/socket-io.h>
44 #include <mono/metadata/mono-endian.h>
45 #include <mono/metadata/tokentype.h>
46 #include <mono/metadata/domain-internals.h>
47 #include <mono/metadata/metadata-internals.h>
48 #include <mono/metadata/class-internals.h>
49 #include <mono/metadata/marshal.h>
50 #include <mono/metadata/gc-internal.h>
51 #include <mono/metadata/mono-gc.h>
52 #include <mono/metadata/rand.h>
53 #include <mono/metadata/sysmath.h>
54 #include <mono/metadata/string-icalls.h>
55 #include <mono/metadata/debug-helpers.h>
56 #include <mono/metadata/process.h>
57 #include <mono/metadata/environment.h>
58 #include <mono/metadata/profiler-private.h>
59 #include <mono/metadata/locales.h>
60 #include <mono/metadata/filewatcher.h>
61 #include <mono/metadata/char-conversions.h>
62 #include <mono/metadata/security.h>
63 #include <mono/metadata/mono-config.h>
64 #include <mono/metadata/cil-coff.h>
65 #include <mono/metadata/number-formatter.h>
66 #include <mono/metadata/security-manager.h>
67 #include <mono/metadata/security-core-clr.h>
68 #include <mono/metadata/mono-perfcounters.h>
69 #include <mono/metadata/mono-debug.h>
70 #include <mono/io-layer/io-layer.h>
71 #include <mono/utils/strtod.h>
72 #include <mono/utils/monobitset.h>
73 #include <mono/utils/mono-time.h>
74 #include <mono/utils/mono-proclib.h>
76 #if defined (PLATFORM_WIN32)
82 static MonoReflectionAssembly
* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
85 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
);
87 static inline MonoBoolean
88 is_generic_parameter (MonoType
*type
)
90 return !type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
);
94 * We expect a pointer to a char, not a string
97 mono_double_ParseImpl (char *ptr
, double *result
)
106 *result
= strtod (ptr
, &endptr
);
110 /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
111 EnterCriticalSection (&mono_strtod_mutex
);
112 *result
= mono_strtod (ptr
, &endptr
);
113 LeaveCriticalSection (&mono_strtod_mutex
);
115 *result
= mono_strtod (ptr
, &endptr
);
120 if (!*ptr
|| (endptr
&& *endptr
))
127 ves_icall_System_Array_GetValueImpl (MonoObject
*this, guint32 pos
)
136 ao
= (MonoArray
*)this;
137 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
139 esize
= mono_array_element_size (ac
);
140 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
142 if (ac
->element_class
->valuetype
)
143 return mono_value_box (this->vtable
->domain
, ac
->element_class
, ea
);
149 ves_icall_System_Array_GetValue (MonoObject
*this, MonoObject
*idxs
)
157 MONO_CHECK_ARG_NULL (idxs
);
159 io
= (MonoArray
*)idxs
;
160 ic
= (MonoClass
*)io
->obj
.vtable
->klass
;
162 ao
= (MonoArray
*)this;
163 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
165 g_assert (ic
->rank
== 1);
166 if (io
->bounds
!= NULL
|| io
->max_length
!= ac
->rank
)
167 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
169 ind
= (gint32
*)io
->vector
;
171 if (ao
->bounds
== NULL
) {
172 if (*ind
< 0 || *ind
>= ao
->max_length
)
173 mono_raise_exception (mono_get_exception_index_out_of_range ());
175 return ves_icall_System_Array_GetValueImpl (this, *ind
);
178 for (i
= 0; i
< ac
->rank
; i
++)
179 if ((ind
[i
] < ao
->bounds
[i
].lower_bound
) ||
180 (ind
[i
] >= (mono_array_lower_bound_t
)ao
->bounds
[i
].length
+ ao
->bounds
[i
].lower_bound
))
181 mono_raise_exception (mono_get_exception_index_out_of_range ());
183 pos
= ind
[0] - ao
->bounds
[0].lower_bound
;
184 for (i
= 1; i
< ac
->rank
; i
++)
185 pos
= pos
*ao
->bounds
[i
].length
+ ind
[i
] -
186 ao
->bounds
[i
].lower_bound
;
188 return ves_icall_System_Array_GetValueImpl (this, pos
);
192 ves_icall_System_Array_SetValueImpl (MonoArray
*this, MonoObject
*value
, guint32 pos
)
194 MonoClass
*ac
, *vc
, *ec
;
206 vc
= value
->vtable
->klass
;
210 ac
= this->obj
.vtable
->klass
;
211 ec
= ac
->element_class
;
213 esize
= mono_array_element_size (ac
);
214 ea
= (gpointer
*)((char*)this->vector
+ (pos
* esize
));
215 va
= (gpointer
*)((char*)value
+ sizeof (MonoObject
));
218 memset (ea
, 0, esize
);
222 #define NO_WIDENING_CONVERSION G_STMT_START{\
223 mono_raise_exception (mono_get_exception_argument ( \
224 "value", "not a widening conversion")); \
227 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
228 if (esize < vsize + (extra)) \
229 mono_raise_exception (mono_get_exception_argument ( \
230 "value", "not a widening conversion")); \
233 #define INVALID_CAST G_STMT_START{\
234 mono_raise_exception (mono_get_exception_invalid_cast ()); \
237 /* Check element (destination) type. */
238 switch (ec
->byval_arg
.type
) {
239 case MONO_TYPE_STRING
:
240 switch (vc
->byval_arg
.type
) {
241 case MONO_TYPE_STRING
:
247 case MONO_TYPE_BOOLEAN
:
248 switch (vc
->byval_arg
.type
) {
249 case MONO_TYPE_BOOLEAN
:
262 NO_WIDENING_CONVERSION
;
269 if (!ec
->valuetype
) {
270 if (!mono_object_isinst (value
, ec
))
272 mono_gc_wbarrier_set_arrayref (this, ea
, (MonoObject
*)value
);
276 if (mono_object_isinst (value
, ec
)) {
277 if (ec
->has_references
)
278 mono_value_copy (ea
, (char*)value
+ sizeof (MonoObject
), ec
);
280 memcpy (ea
, (char *)value
+ sizeof (MonoObject
), esize
);
287 vsize
= mono_class_instance_size (vc
) - sizeof (MonoObject
);
289 et
= ec
->byval_arg
.type
;
290 if (et
== MONO_TYPE_VALUETYPE
&& ec
->byval_arg
.data
.klass
->enumtype
)
291 et
= mono_class_enum_basetype (ec
->byval_arg
.data
.klass
)->type
;
293 vt
= vc
->byval_arg
.type
;
294 if (vt
== MONO_TYPE_VALUETYPE
&& vc
->byval_arg
.data
.klass
->enumtype
)
295 vt
= mono_class_enum_basetype (vc
->byval_arg
.data
.klass
)->type
;
297 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
303 case MONO_TYPE_CHAR: \
304 CHECK_WIDENING_CONVERSION(0); \
305 *(etype *) ea = (etype) u64; \
307 /* You can't assign a signed value to an unsigned array. */ \
312 /* You can't assign a floating point number to an integer array. */ \
315 NO_WIDENING_CONVERSION; \
319 #define ASSIGN_SIGNED(etype) G_STMT_START{\
325 CHECK_WIDENING_CONVERSION(0); \
326 *(etype *) ea = (etype) i64; \
328 /* You can assign an unsigned value to a signed array if the array's */ \
329 /* element size is larger than the value size. */ \
334 case MONO_TYPE_CHAR: \
335 CHECK_WIDENING_CONVERSION(1); \
336 *(etype *) ea = (etype) u64; \
338 /* You can't assign a floating point number to an integer array. */ \
341 NO_WIDENING_CONVERSION; \
345 #define ASSIGN_REAL(etype) G_STMT_START{\
349 CHECK_WIDENING_CONVERSION(0); \
350 *(etype *) ea = (etype) r64; \
352 /* All integer values fit into a floating point array, so we don't */ \
353 /* need to CHECK_WIDENING_CONVERSION here. */ \
358 *(etype *) ea = (etype) i64; \
364 case MONO_TYPE_CHAR: \
365 *(etype *) ea = (etype) u64; \
372 u64
= *(guint8
*) va
;
375 u64
= *(guint16
*) va
;
378 u64
= *(guint32
*) va
;
381 u64
= *(guint64
*) va
;
387 i64
= *(gint16
*) va
;
390 i64
= *(gint32
*) va
;
393 i64
= *(gint64
*) va
;
396 r64
= *(gfloat
*) va
;
399 r64
= *(gdouble
*) va
;
402 u64
= *(guint16
*) va
;
404 case MONO_TYPE_BOOLEAN
:
405 /* Boolean is only compatible with itself. */
418 NO_WIDENING_CONVERSION
;
425 /* If we can't do a direct copy, let's try a widening conversion. */
428 ASSIGN_UNSIGNED (guint16
);
430 ASSIGN_UNSIGNED (guint8
);
432 ASSIGN_UNSIGNED (guint16
);
434 ASSIGN_UNSIGNED (guint32
);
436 ASSIGN_UNSIGNED (guint64
);
438 ASSIGN_SIGNED (gint8
);
440 ASSIGN_SIGNED (gint16
);
442 ASSIGN_SIGNED (gint32
);
444 ASSIGN_SIGNED (gint64
);
446 ASSIGN_REAL (gfloat
);
448 ASSIGN_REAL (gdouble
);
452 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
456 #undef NO_WIDENING_CONVERSION
457 #undef CHECK_WIDENING_CONVERSION
458 #undef ASSIGN_UNSIGNED
464 ves_icall_System_Array_SetValue (MonoArray
*this, MonoObject
*value
,
472 MONO_CHECK_ARG_NULL (idxs
);
474 ic
= idxs
->obj
.vtable
->klass
;
475 ac
= this->obj
.vtable
->klass
;
477 g_assert (ic
->rank
== 1);
478 if (idxs
->bounds
!= NULL
|| idxs
->max_length
!= ac
->rank
)
479 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
481 ind
= (gint32
*)idxs
->vector
;
483 if (this->bounds
== NULL
) {
484 if (*ind
< 0 || *ind
>= this->max_length
)
485 mono_raise_exception (mono_get_exception_index_out_of_range ());
487 ves_icall_System_Array_SetValueImpl (this, value
, *ind
);
491 for (i
= 0; i
< ac
->rank
; i
++)
492 if ((ind
[i
] < this->bounds
[i
].lower_bound
) ||
493 (ind
[i
] >= (mono_array_lower_bound_t
)this->bounds
[i
].length
+ this->bounds
[i
].lower_bound
))
494 mono_raise_exception (mono_get_exception_index_out_of_range ());
496 pos
= ind
[0] - this->bounds
[0].lower_bound
;
497 for (i
= 1; i
< ac
->rank
; i
++)
498 pos
= pos
* this->bounds
[i
].length
+ ind
[i
] -
499 this->bounds
[i
].lower_bound
;
501 ves_icall_System_Array_SetValueImpl (this, value
, pos
);
505 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
509 mono_array_size_t
*sizes
, i
;
510 gboolean bounded
= FALSE
;
514 MONO_CHECK_ARG_NULL (type
);
515 MONO_CHECK_ARG_NULL (lengths
);
517 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
519 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
521 for (i
= 0; i
< mono_array_length (lengths
); i
++)
522 if (mono_array_get (lengths
, gint32
, i
) < 0)
523 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
525 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint32
, 0) != 0))
526 /* vectors are not the same as one dimensional arrays with no-zero bounds */
531 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
533 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
534 for (i
= 0; i
< aklass
->rank
; ++i
) {
535 sizes
[i
] = mono_array_get (lengths
, guint32
, i
);
537 sizes
[i
+ aklass
->rank
] = mono_array_get (bounds
, guint32
, i
);
539 sizes
[i
+ aklass
->rank
] = 0;
542 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
548 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
552 mono_array_size_t
*sizes
, i
;
553 gboolean bounded
= FALSE
;
557 MONO_CHECK_ARG_NULL (type
);
558 MONO_CHECK_ARG_NULL (lengths
);
560 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
562 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
564 for (i
= 0; i
< mono_array_length (lengths
); i
++)
565 if ((mono_array_get (lengths
, gint64
, i
) < 0) ||
566 (mono_array_get (lengths
, gint64
, i
) > MONO_ARRAY_MAX_INDEX
))
567 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
569 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint64
, 0) != 0))
570 /* vectors are not the same as one dimensional arrays with no-zero bounds */
575 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
577 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
578 for (i
= 0; i
< aklass
->rank
; ++i
) {
579 sizes
[i
] = mono_array_get (lengths
, guint64
, i
);
581 sizes
[i
+ aklass
->rank
] = (mono_array_size_t
) mono_array_get (bounds
, guint64
, i
);
583 sizes
[i
+ aklass
->rank
] = 0;
586 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
592 ves_icall_System_Array_GetRank (MonoObject
*this)
596 return this->vtable
->klass
->rank
;
600 ves_icall_System_Array_GetLength (MonoArray
*this, gint32 dimension
)
602 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
603 mono_array_size_t length
;
607 if ((dimension
< 0) || (dimension
>= rank
))
608 mono_raise_exception (mono_get_exception_index_out_of_range ());
610 if (this->bounds
== NULL
)
611 length
= this->max_length
;
613 length
= this->bounds
[dimension
].length
;
615 #ifdef MONO_BIG_ARRAYS
616 if (length
> G_MAXINT32
)
617 mono_raise_exception (mono_get_exception_overflow ());
623 ves_icall_System_Array_GetLongLength (MonoArray
*this, gint32 dimension
)
625 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
629 if ((dimension
< 0) || (dimension
>= rank
))
630 mono_raise_exception (mono_get_exception_index_out_of_range ());
632 if (this->bounds
== NULL
)
633 return this->max_length
;
635 return this->bounds
[dimension
].length
;
639 ves_icall_System_Array_GetLowerBound (MonoArray
*this, gint32 dimension
)
641 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
645 if ((dimension
< 0) || (dimension
>= rank
))
646 mono_raise_exception (mono_get_exception_index_out_of_range ());
648 if (this->bounds
== NULL
)
651 return this->bounds
[dimension
].lower_bound
;
655 ves_icall_System_Array_ClearInternal (MonoArray
*arr
, int idx
, int length
)
657 int sz
= mono_array_element_size (mono_object_class (arr
));
658 memset (mono_array_addr_with_size (arr
, sz
, idx
), 0, length
* sz
);
662 ves_icall_System_Array_FastCopy (MonoArray
*source
, int source_idx
, MonoArray
* dest
, int dest_idx
, int length
)
667 MonoClass
*src_class
;
668 MonoClass
*dest_class
;
673 if (source
->obj
.vtable
->klass
->rank
!= dest
->obj
.vtable
->klass
->rank
)
676 if (source
->bounds
|| dest
->bounds
)
679 if ((dest_idx
+ length
> mono_array_length (dest
)) ||
680 (source_idx
+ length
> mono_array_length (source
)))
683 src_class
= source
->obj
.vtable
->klass
->element_class
;
684 dest_class
= dest
->obj
.vtable
->klass
->element_class
;
687 * Handle common cases.
690 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
691 if (src_class
== mono_defaults
.object_class
&& dest_class
->valuetype
) {
692 int has_refs
= dest_class
->has_references
;
693 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
694 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
695 if (elem
&& !mono_object_isinst (elem
, dest_class
))
699 element_size
= mono_array_element_size (dest
->obj
.vtable
->klass
);
700 memset (mono_array_addr_with_size (dest
, element_size
, dest_idx
), 0, element_size
* length
);
701 for (i
= 0; i
< length
; ++i
) {
702 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, source_idx
+ i
);
703 void *addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
+ i
);
707 mono_value_copy (addr
, (char *)elem
+ sizeof (MonoObject
), dest_class
);
709 memcpy (addr
, (char *)elem
+ sizeof (MonoObject
), element_size
);
714 /* Check if we're copying a char[] <==> (u)short[] */
715 if (src_class
!= dest_class
) {
716 if (dest_class
->valuetype
|| dest_class
->enumtype
|| src_class
->valuetype
|| src_class
->enumtype
)
719 if (mono_class_is_subclass_of (src_class
, dest_class
, FALSE
))
721 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
722 else if (mono_class_is_subclass_of (dest_class
, src_class
, FALSE
))
723 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
724 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
725 if (elem
&& !mono_object_isinst (elem
, dest_class
))
732 if (dest_class
->valuetype
) {
733 element_size
= mono_array_element_size (source
->obj
.vtable
->klass
);
734 source_addr
= mono_array_addr_with_size (source
, element_size
, source_idx
);
735 if (dest_class
->has_references
) {
736 mono_value_copy_array (dest
, dest_idx
, source_addr
, length
);
738 dest_addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
);
739 memmove (dest_addr
, source_addr
, element_size
* length
);
742 mono_array_memcpy_refs (dest
, dest_idx
, source
, source_idx
, length
);
749 ves_icall_System_Array_GetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
758 ao
= (MonoArray
*)this;
759 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
761 esize
= mono_array_element_size (ac
);
762 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
764 memcpy (value
, ea
, esize
);
768 ves_icall_System_Array_SetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
777 ao
= (MonoArray
*)this;
778 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
780 esize
= mono_array_element_size (ac
);
781 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
783 memcpy (ea
, value
, esize
);
787 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray
*array
, MonoClassField
*field_handle
)
789 MonoClass
*klass
= array
->obj
.vtable
->klass
;
790 guint32 size
= mono_array_element_size (klass
);
791 MonoType
*type
= mono_type_get_underlying_type (&klass
->element_class
->byval_arg
);
793 const char *field_data
;
795 if (MONO_TYPE_IS_REFERENCE (type
) ||
796 (type
->type
== MONO_TYPE_VALUETYPE
&&
797 (!mono_type_get_class (type
) ||
798 mono_type_get_class (type
)->has_references
))) {
799 MonoException
*exc
= mono_get_exception_argument("array",
800 "Cannot initialize array containing references");
801 mono_raise_exception (exc
);
804 if (!(field_handle
->type
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) {
805 MonoException
*exc
= mono_get_exception_argument("field_handle",
806 "Field doesn't have an RVA");
807 mono_raise_exception (exc
);
810 size
*= array
->max_length
;
811 field_data
= mono_field_get_data (field_handle
);
813 if (size
> mono_type_size (field_handle
->type
, &align
)) {
814 MonoException
*exc
= mono_get_exception_argument("field_handle",
815 "Field not large enough to fill array");
816 mono_raise_exception (exc
);
819 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
821 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
822 guint ## n *src = (guint ## n *) field_data; \
823 guint ## n *end = (guint ## n *)((char*)src + size); \
825 for (; src < end; data++, src++) { \
826 *data = read ## n (src); \
830 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
832 switch (type
->type
) {
849 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
853 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
855 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_R8
) {
858 double *data
= (double*)mono_array_addr (array
, double, 0);
860 for (i
= 0; i
< size
; i
++, data
++) {
870 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
874 return offsetof (MonoString
, chars
);
878 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject
*obj
)
882 if ((obj
== NULL
) || (! (obj
->vtable
->klass
->valuetype
)))
885 return mono_object_clone (obj
);
889 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType
*handle
)
895 MONO_CHECK_ARG_NULL (handle
);
897 klass
= mono_class_from_mono_type (handle
);
898 MONO_CHECK_ARG (handle
, klass
);
900 /* This will call the type constructor */
901 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass
));
905 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage
*image
)
909 mono_image_check_for_module_cctor (image
);
910 if (image
->has_module_cctor
) {
911 MonoClass
*module_klass
= mono_class_get (image
, MONO_TOKEN_TYPE_DEF
| 1);
912 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass
));
917 ves_icall_System_Object_MemberwiseClone (MonoObject
*this)
921 return mono_object_clone (this);
925 ves_icall_System_ValueType_InternalGetHashCode (MonoObject
*this, MonoArray
**fields
)
928 MonoObject
**values
= NULL
;
932 MonoClassField
* field
;
937 klass
= mono_object_class (this);
939 if (mono_class_num_fields (klass
) == 0)
940 return mono_object_hash (this);
943 * Compute the starting value of the hashcode for fields of primitive
944 * types, and return the remaining fields in an array to the managed side.
945 * This way, we can avoid costly reflection operations in managed code.
948 while ((field
= mono_class_get_fields (klass
, &iter
))) {
949 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
951 if (mono_field_is_deleted (field
))
953 /* FIXME: Add more types */
954 switch (field
->type
->type
) {
956 result
^= *(gint32
*)((guint8
*)this + field
->offset
);
958 case MONO_TYPE_STRING
: {
960 s
= *(MonoString
**)((guint8
*)this + field
->offset
);
962 result
^= mono_string_hash (s
);
967 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
));
968 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
969 values
[count
++] = o
;
975 *fields
= mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
);
976 for (i
= 0; i
< count
; ++i
)
977 mono_array_setref (*fields
, i
, values
[i
]);
985 ves_icall_System_ValueType_Equals (MonoObject
*this, MonoObject
*that
, MonoArray
**fields
)
988 MonoObject
**values
= NULL
;
990 MonoClassField
* field
;
996 MONO_CHECK_ARG_NULL (that
);
998 if (this->vtable
!= that
->vtable
)
1001 klass
= mono_object_class (this);
1003 if (klass
->enumtype
&& mono_class_enum_basetype (klass
) && mono_class_enum_basetype (klass
)->type
== MONO_TYPE_I4
)
1004 return (*(gint32
*)((guint8
*)this + sizeof (MonoObject
)) == *(gint32
*)((guint8
*)that
+ sizeof (MonoObject
)));
1007 * Do the comparison for fields of primitive type and return a result if
1008 * possible. Otherwise, return the remaining fields in an array to the
1009 * managed side. This way, we can avoid costly reflection operations in
1014 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1015 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1017 if (mono_field_is_deleted (field
))
1019 /* FIXME: Add more types */
1020 switch (field
->type
->type
) {
1023 case MONO_TYPE_BOOLEAN
:
1024 if (*((guint8
*)this + field
->offset
) != *((guint8
*)that
+ field
->offset
))
1029 case MONO_TYPE_CHAR
:
1030 if (*(gint16
*)((guint8
*)this + field
->offset
) != *(gint16
*)((guint8
*)that
+ field
->offset
))
1035 if (*(gint32
*)((guint8
*)this + field
->offset
) != *(gint32
*)((guint8
*)that
+ field
->offset
))
1040 if (*(gint64
*)((guint8
*)this + field
->offset
) != *(gint64
*)((guint8
*)that
+ field
->offset
))
1044 if (*(float*)((guint8
*)this + field
->offset
) != *(float*)((guint8
*)that
+ field
->offset
))
1048 if (*(double*)((guint8
*)this + field
->offset
) != *(double*)((guint8
*)that
+ field
->offset
))
1053 case MONO_TYPE_STRING
: {
1054 MonoString
*s1
, *s2
;
1055 guint32 s1len
, s2len
;
1056 s1
= *(MonoString
**)((guint8
*)this + field
->offset
);
1057 s2
= *(MonoString
**)((guint8
*)that
+ field
->offset
);
1060 if ((s1
== NULL
) || (s2
== NULL
))
1062 s1len
= mono_string_length (s1
);
1063 s2len
= mono_string_length (s2
);
1067 if (memcmp (mono_string_chars (s1
), mono_string_chars (s2
), s1len
* sizeof (gunichar2
)) != 0)
1073 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
) * 2);
1074 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1075 values
[count
++] = o
;
1076 o
= mono_field_get_value_object (mono_object_domain (this), field
, that
);
1077 values
[count
++] = o
;
1080 if (klass
->enumtype
)
1081 /* enums only have one non-static field */
1087 *fields
= mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
);
1088 for (i
= 0; i
< count
; ++i
)
1089 mono_array_setref (*fields
, i
, values
[i
]);
1096 static MonoReflectionType
*
1097 ves_icall_System_Object_GetType (MonoObject
*obj
)
1099 MONO_ARCH_SAVE_REGS
;
1101 if (obj
->vtable
->klass
!= mono_defaults
.transparent_proxy_class
)
1102 return mono_type_get_object (mono_object_domain (obj
), &obj
->vtable
->klass
->byval_arg
);
1104 return mono_type_get_object (mono_object_domain (obj
), &((MonoTransparentProxy
*)obj
)->remote_class
->proxy_class
->byval_arg
);
1108 mono_type_type_from_obj (MonoReflectionType
*mtype
, MonoObject
*obj
)
1110 MONO_ARCH_SAVE_REGS
;
1112 mtype
->type
= &obj
->vtable
->klass
->byval_arg
;
1113 g_assert (mtype
->type
->type
);
1117 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
)
1119 MONO_ARCH_SAVE_REGS
;
1121 MONO_CHECK_ARG_NULL (obj
);
1123 return mono_image_create_token (mb
->dynamic_image
, obj
, TRUE
, TRUE
);
1127 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder
*mb
,
1128 MonoReflectionMethod
*method
,
1129 MonoArray
*opt_param_types
)
1131 MONO_ARCH_SAVE_REGS
;
1133 MONO_CHECK_ARG_NULL (method
);
1135 return mono_image_create_method_token (
1136 mb
->dynamic_image
, (MonoObject
*) method
, opt_param_types
);
1140 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
1142 MONO_ARCH_SAVE_REGS
;
1144 mono_image_create_pefile (mb
, file
);
1148 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
1150 MONO_ARCH_SAVE_REGS
;
1152 mono_image_build_metadata (mb
);
1156 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, guint32 token
)
1158 MONO_ARCH_SAVE_REGS
;
1160 mono_image_register_token (mb
->dynamic_image
, token
, obj
);
1164 get_caller (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1166 MonoMethod
**dest
= data
;
1168 /* skip unmanaged frames */
1184 get_executing (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1186 MonoMethod
**dest
= data
;
1188 /* skip unmanaged frames */
1193 if (!strcmp (m
->klass
->name_space
, "System.Reflection"))
1202 get_caller_no_reflection (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1204 MonoMethod
**dest
= data
;
1206 /* skip unmanaged frames */
1210 if (m
->wrapper_type
!= MONO_WRAPPER_NONE
)
1213 if (m
->klass
->image
== mono_defaults
.corlib
&& !strcmp (m
->klass
->name_space
, "System.Reflection"))
1227 static MonoReflectionType
*
1228 type_from_name (const char *str
, MonoBoolean ignoreCase
)
1230 MonoType
*type
= NULL
;
1231 MonoAssembly
*assembly
= NULL
;
1232 MonoTypeNameParse info
;
1233 char *temp_str
= g_strdup (str
);
1234 gboolean type_resolve
= FALSE
;
1236 MONO_ARCH_SAVE_REGS
;
1238 /* mono_reflection_parse_type() mangles the string */
1239 if (!mono_reflection_parse_type (temp_str
, &info
)) {
1240 mono_reflection_free_type_info (&info
);
1245 if (info
.assembly
.name
) {
1246 assembly
= mono_assembly_load (&info
.assembly
, NULL
, NULL
);
1248 MonoMethod
*m
= mono_method_get_last_managed ();
1249 MonoMethod
*dest
= m
;
1251 mono_stack_walk_no_il (get_caller_no_reflection
, &dest
);
1256 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1257 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1258 * to crash. This only seems to happen in some strange remoting
1259 * scenarios and I was unable to figure out what's happening there.
1260 * Dec 10, 2005 - Martin.
1264 assembly
= dest
->klass
->image
->assembly
;
1266 g_warning (G_STRLOC
);
1271 type
= mono_reflection_get_type (assembly
->image
, &info
, ignoreCase
, &type_resolve
);
1273 if (!info
.assembly
.name
&& !type
) /* try mscorlib */
1274 type
= mono_reflection_get_type (NULL
, &info
, ignoreCase
, &type_resolve
);
1276 mono_reflection_free_type_info (&info
);
1282 return mono_type_get_object (mono_domain_get (), type
);
1286 MonoReflectionType
*
1287 mono_type_get (const char *str
)
1289 char *copy
= g_strdup (str
);
1290 MonoReflectionType
*type
= type_from_name (copy
, FALSE
);
1297 static MonoReflectionType
*
1298 ves_icall_type_from_name (MonoString
*name
,
1299 MonoBoolean throwOnError
,
1300 MonoBoolean ignoreCase
)
1302 char *str
= mono_string_to_utf8 (name
);
1303 MonoReflectionType
*type
;
1305 type
= type_from_name (str
, ignoreCase
);
1308 MonoException
*e
= NULL
;
1311 e
= mono_get_exception_type_load (name
, NULL
);
1313 mono_loader_clear_error ();
1315 mono_raise_exception (e
);
1322 static MonoReflectionType
*
1323 ves_icall_type_from_handle (MonoType
*handle
)
1325 MonoDomain
*domain
= mono_domain_get ();
1326 MonoClass
*klass
= mono_class_from_mono_type (handle
);
1328 MONO_ARCH_SAVE_REGS
;
1330 mono_class_init (klass
);
1331 return mono_type_get_object (domain
, handle
);
1335 ves_icall_System_Type_EqualsInternal (MonoReflectionType
*type
, MonoReflectionType
*c
)
1337 MONO_ARCH_SAVE_REGS
;
1339 if (c
&& type
->type
&& c
->type
)
1340 return mono_metadata_type_equal (type
->type
, c
->type
);
1342 return (type
== c
) ? TRUE
: FALSE
;
1345 /* System.TypeCode */
1364 TYPECODE_STRING
= 18
1368 ves_icall_type_GetTypeCodeInternal (MonoReflectionType
*type
)
1370 int t
= type
->type
->type
;
1372 MONO_ARCH_SAVE_REGS
;
1374 if (type
->type
->byref
)
1375 return TYPECODE_OBJECT
;
1379 case MONO_TYPE_VOID
:
1380 return TYPECODE_OBJECT
;
1381 case MONO_TYPE_BOOLEAN
:
1382 return TYPECODE_BOOLEAN
;
1384 return TYPECODE_BYTE
;
1386 return TYPECODE_SBYTE
;
1388 return TYPECODE_UINT16
;
1390 return TYPECODE_INT16
;
1391 case MONO_TYPE_CHAR
:
1392 return TYPECODE_CHAR
;
1396 return TYPECODE_OBJECT
;
1398 return TYPECODE_UINT32
;
1400 return TYPECODE_INT32
;
1402 return TYPECODE_UINT64
;
1404 return TYPECODE_INT64
;
1406 return TYPECODE_SINGLE
;
1408 return TYPECODE_DOUBLE
;
1409 case MONO_TYPE_VALUETYPE
:
1410 if (type
->type
->data
.klass
->enumtype
) {
1411 t
= mono_class_enum_basetype (type
->type
->data
.klass
)->type
;
1414 MonoClass
*k
= type
->type
->data
.klass
;
1415 if (strcmp (k
->name_space
, "System") == 0) {
1416 if (strcmp (k
->name
, "Decimal") == 0)
1417 return TYPECODE_DECIMAL
;
1418 else if (strcmp (k
->name
, "DateTime") == 0)
1419 return TYPECODE_DATETIME
;
1422 return TYPECODE_OBJECT
;
1423 case MONO_TYPE_STRING
:
1424 return TYPECODE_STRING
;
1425 case MONO_TYPE_SZARRAY
:
1426 case MONO_TYPE_ARRAY
:
1427 case MONO_TYPE_OBJECT
:
1429 case MONO_TYPE_MVAR
:
1430 case MONO_TYPE_TYPEDBYREF
:
1431 return TYPECODE_OBJECT
;
1432 case MONO_TYPE_CLASS
:
1434 MonoClass
*k
= type
->type
->data
.klass
;
1435 if (strcmp (k
->name_space
, "System") == 0) {
1436 if (strcmp (k
->name
, "DBNull") == 0)
1437 return TYPECODE_DBNULL
;
1440 return TYPECODE_OBJECT
;
1441 case MONO_TYPE_GENERICINST
:
1442 return TYPECODE_OBJECT
;
1444 g_error ("type 0x%02x not handled in GetTypeCode()", t
);
1450 ves_icall_type_is_subtype_of (MonoReflectionType
*type
, MonoReflectionType
*c
, MonoBoolean check_interfaces
)
1456 MONO_ARCH_SAVE_REGS
;
1458 g_assert (type
!= NULL
);
1460 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1462 if (!c
) /* FIXME: dont know what do do here */
1465 klass
= mono_class_from_mono_type (type
->type
);
1466 klassc
= mono_class_from_mono_type (c
->type
);
1468 if (type
->type
->byref
)
1469 return klassc
== mono_defaults
.object_class
;
1471 return mono_class_is_subclass_of (klass
, klassc
, check_interfaces
);
1475 ves_icall_type_is_assignable_from (MonoReflectionType
*type
, MonoReflectionType
*c
)
1481 MONO_ARCH_SAVE_REGS
;
1483 g_assert (type
!= NULL
);
1485 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1487 klass
= mono_class_from_mono_type (type
->type
);
1488 klassc
= mono_class_from_mono_type (c
->type
);
1490 if (type
->type
->byref
&& !c
->type
->byref
)
1493 return mono_class_is_assignable_from (klass
, klassc
);
1497 ves_icall_type_IsInstanceOfType (MonoReflectionType
*type
, MonoObject
*obj
)
1499 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1500 return mono_object_isinst (obj
, klass
) != NULL
;
1504 ves_icall_get_attributes (MonoReflectionType
*type
)
1506 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1508 MONO_ARCH_SAVE_REGS
;
1510 return klass
->flags
;
1513 static MonoReflectionMarshal
*
1514 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField
*field
)
1516 MonoClass
*klass
= field
->field
->parent
;
1517 MonoMarshalType
*info
;
1520 if (klass
->generic_container
||
1521 (klass
->generic_class
&& klass
->generic_class
->context
.class_inst
->is_open
))
1524 info
= mono_marshal_load_type_info (klass
);
1526 for (i
= 0; i
< info
->num_fields
; ++i
) {
1527 if (info
->fields
[i
].field
== field
->field
) {
1528 if (!info
->fields
[i
].mspec
)
1531 return mono_reflection_marshal_from_marshal_spec (field
->object
.vtable
->domain
, klass
, info
->fields
[i
].mspec
);
1538 static MonoReflectionField
*
1539 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
*handle
, MonoClass
*klass
)
1544 klass
= handle
->parent
;
1546 /* FIXME: check that handle is a field of klass or of a parent: return null
1547 * and throw the exception in managed code.
1549 return mono_field_get_object (mono_domain_get (), klass
, handle
);
1552 static MonoReflectionField
*
1553 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField
*handle
)
1555 MONO_ARCH_SAVE_REGS
;
1559 return mono_field_get_object (mono_domain_get (), handle
->parent
, handle
);
1563 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField
*field
, MonoBoolean optional
)
1565 MonoType
*type
= field
->field
->type
;
1567 return type_array_from_modifiers (field
->field
->parent
->image
, type
, optional
);
1571 ves_icall_get_method_info (MonoMethod
*method
, MonoMethodInfo
*info
)
1573 MonoDomain
*domain
= mono_domain_get ();
1574 MonoMethodSignature
* sig
;
1575 MONO_ARCH_SAVE_REGS
;
1577 sig
= mono_method_signature (method
);
1579 g_assert (mono_loader_get_last_error ());
1580 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1583 info
->parent
= mono_type_get_object (domain
, &method
->klass
->byval_arg
);
1584 info
->ret
= mono_type_get_object (domain
, sig
->ret
);
1585 info
->attrs
= method
->flags
;
1586 info
->implattrs
= method
->iflags
;
1587 if (sig
->call_convention
== MONO_CALL_DEFAULT
)
1588 info
->callconv
= sig
->sentinelpos
>= 0 ? 2 : 1;
1590 if (sig
->call_convention
== MONO_CALL_VARARG
|| sig
->sentinelpos
>= 0)
1595 info
->callconv
|= (sig
->hasthis
<< 5) | (sig
->explicit_this
<< 6);
1599 ves_icall_get_parameter_info (MonoMethod
*method
)
1601 MonoDomain
*domain
= mono_domain_get ();
1603 return mono_param_get_objects (domain
, method
);
1606 static MonoReflectionMarshal
*
1607 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod
*method
)
1609 MonoDomain
*domain
= mono_domain_get ();
1610 MonoReflectionMarshal
* res
= NULL
;
1611 MonoMarshalSpec
**mspecs
;
1614 mspecs
= g_new (MonoMarshalSpec
*, mono_method_signature (method
)->param_count
+ 1);
1615 mono_method_get_marshal_info (method
, mspecs
);
1618 res
= mono_reflection_marshal_from_marshal_spec (domain
, method
->klass
, mspecs
[0]);
1620 for (i
= mono_method_signature (method
)->param_count
; i
>= 0; i
--)
1622 mono_metadata_free_marshal_spec (mspecs
[i
]);
1629 ves_icall_MonoField_GetFieldOffset (MonoReflectionField
*field
)
1631 return field
->field
->offset
- sizeof (MonoObject
);
1634 static MonoReflectionType
*
1635 ves_icall_MonoField_GetParentType (MonoReflectionField
*field
, MonoBoolean declaring
)
1638 MONO_ARCH_SAVE_REGS
;
1640 parent
= declaring
? field
->field
->parent
: field
->klass
;
1642 return mono_type_get_object (mono_object_domain (field
), &parent
->byval_arg
);
1646 ves_icall_MonoField_GetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
)
1649 MonoClassField
*cf
= field
->field
;
1653 MonoDomain
*domain
= mono_object_domain (field
);
1655 gboolean is_static
= FALSE
;
1656 gboolean is_ref
= FALSE
;
1658 MONO_ARCH_SAVE_REGS
;
1660 if (field
->klass
->image
->assembly
->ref_only
)
1661 mono_raise_exception (mono_get_exception_invalid_operation (
1662 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1664 mono_class_init (field
->klass
);
1666 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1669 if (obj
&& !is_static
) {
1670 /* Check that the field belongs to the object */
1671 gboolean found
= FALSE
;
1674 for (k
= obj
->vtable
->klass
; k
; k
= k
->parent
) {
1675 if (k
== cf
->parent
) {
1682 char *msg
= g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf
), cf
->parent
->name
, obj
->vtable
->klass
->name
);
1683 MonoException
*ex
= mono_get_exception_argument (NULL
, msg
);
1685 mono_raise_exception (ex
);
1689 t
= mono_type_get_underlying_type (cf
->type
);
1691 case MONO_TYPE_STRING
:
1692 case MONO_TYPE_OBJECT
:
1693 case MONO_TYPE_CLASS
:
1694 case MONO_TYPE_ARRAY
:
1695 case MONO_TYPE_SZARRAY
:
1700 case MONO_TYPE_BOOLEAN
:
1703 case MONO_TYPE_CHAR
:
1712 case MONO_TYPE_VALUETYPE
:
1715 case MONO_TYPE_GENERICINST
:
1716 if (mono_type_generic_inst_is_valuetype (t
)) {
1723 g_error ("type 0x%x not handled in "
1724 "ves_icall_Monofield_GetValue", t
->type
);
1730 vtable
= mono_class_vtable (domain
, cf
->parent
);
1731 if (!vtable
->initialized
&& !(cf
->type
->attrs
& FIELD_ATTRIBUTE_LITERAL
))
1732 mono_runtime_class_init (vtable
);
1737 mono_field_static_get_value (vtable
, cf
, &o
);
1739 mono_field_get_value (obj
, cf
, &o
);
1744 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1745 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1748 /* Convert the Nullable structure into a boxed vtype */
1750 buf
= (guint8
*)vtable
->data
+ cf
->offset
;
1752 buf
= (guint8
*)obj
+ cf
->offset
;
1754 return mono_nullable_box (buf
, nklass
);
1757 /* boxed value type */
1758 klass
= mono_class_from_mono_type (cf
->type
);
1759 o
= mono_object_new (domain
, klass
);
1760 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1762 mono_field_static_get_value (vtable
, cf
, v
);
1764 mono_field_get_value (obj
, cf
, v
);
1771 ves_icall_MonoField_SetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
, MonoObject
*value
)
1773 MonoClassField
*cf
= field
->field
;
1776 MONO_ARCH_SAVE_REGS
;
1778 if (field
->klass
->image
->assembly
->ref_only
)
1779 mono_raise_exception (mono_get_exception_invalid_operation (
1780 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1782 v
= (gchar
*) value
;
1783 if (!cf
->type
->byref
) {
1784 switch (cf
->type
->type
) {
1787 case MONO_TYPE_BOOLEAN
:
1790 case MONO_TYPE_CHAR
:
1799 case MONO_TYPE_VALUETYPE
:
1801 v
+= sizeof (MonoObject
);
1803 case MONO_TYPE_STRING
:
1804 case MONO_TYPE_OBJECT
:
1805 case MONO_TYPE_CLASS
:
1806 case MONO_TYPE_ARRAY
:
1807 case MONO_TYPE_SZARRAY
:
1810 case MONO_TYPE_GENERICINST
: {
1811 MonoGenericClass
*gclass
= cf
->type
->data
.generic_class
;
1812 g_assert (!gclass
->context
.class_inst
->is_open
);
1814 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1815 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1816 MonoObject
*nullable
;
1819 * Convert the boxed vtype into a Nullable structure.
1820 * This is complicated by the fact that Nullables have
1821 * a variable structure.
1823 nullable
= mono_object_new (mono_domain_get (), nklass
);
1825 mono_nullable_init (mono_object_unbox (nullable
), value
, nklass
);
1827 v
= mono_object_unbox (nullable
);
1830 if (gclass
->container_class
->valuetype
&& (v
!= NULL
))
1831 v
+= sizeof (MonoObject
);
1835 g_error ("type 0x%x not handled in "
1836 "ves_icall_FieldInfo_SetValueInternal", cf
->type
->type
);
1841 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
1842 MonoVTable
*vtable
= mono_class_vtable (mono_object_domain (field
), cf
->parent
);
1843 if (!vtable
->initialized
)
1844 mono_runtime_class_init (vtable
);
1845 mono_field_static_set_value (vtable
, cf
, v
);
1847 mono_field_set_value (obj
, cf
, v
);
1852 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField
*this)
1854 MonoObject
*o
= NULL
;
1855 MonoClassField
*field
= this->field
;
1857 MonoDomain
*domain
= mono_object_domain (this);
1859 MonoTypeEnum def_type
;
1860 const char *def_value
;
1862 MONO_ARCH_SAVE_REGS
;
1864 mono_class_init (field
->parent
);
1866 if (!(field
->type
->attrs
& FIELD_ATTRIBUTE_HAS_DEFAULT
))
1867 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
1869 if (field
->parent
->image
->dynamic
) {
1871 g_assert_not_reached ();
1874 def_value
= mono_class_get_field_default_value (field
, &def_type
);
1879 case MONO_TYPE_BOOLEAN
:
1882 case MONO_TYPE_CHAR
:
1890 case MONO_TYPE_R8
: {
1893 /* boxed value type */
1894 t
= g_new0 (MonoType
, 1);
1896 klass
= mono_class_from_mono_type (t
);
1898 o
= mono_object_new (domain
, klass
);
1899 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1900 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, v
);
1903 case MONO_TYPE_STRING
:
1904 case MONO_TYPE_CLASS
:
1905 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, &o
);
1908 g_assert_not_reached ();
1914 static MonoReflectionType
*
1915 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod
*rmethod
)
1917 MonoMethod
*method
= rmethod
->method
.method
;
1919 return mono_type_get_object (mono_object_domain (rmethod
), &method
->klass
->byval_arg
);
1922 /* From MonoProperty.cs */
1924 PInfo_Attributes
= 1,
1925 PInfo_GetMethod
= 1 << 1,
1926 PInfo_SetMethod
= 1 << 2,
1927 PInfo_ReflectedType
= 1 << 3,
1928 PInfo_DeclaringType
= 1 << 4,
1933 ves_icall_get_property_info (MonoReflectionProperty
*property
, MonoPropertyInfo
*info
, PInfo req_info
)
1935 MonoDomain
*domain
= mono_object_domain (property
);
1937 MONO_ARCH_SAVE_REGS
;
1939 if ((req_info
& PInfo_ReflectedType
) != 0)
1940 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->klass
->byval_arg
));
1941 else if ((req_info
& PInfo_DeclaringType
) != 0)
1942 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->property
->parent
->byval_arg
));
1944 if ((req_info
& PInfo_Name
) != 0)
1945 MONO_STRUCT_SETREF (info
, name
, mono_string_new (domain
, property
->property
->name
));
1947 if ((req_info
& PInfo_Attributes
) != 0)
1948 info
->attrs
= property
->property
->attrs
;
1950 if ((req_info
& PInfo_GetMethod
) != 0)
1951 MONO_STRUCT_SETREF (info
, get
, property
->property
->get
?
1952 mono_method_get_object (domain
, property
->property
->get
, property
->klass
): NULL
);
1954 if ((req_info
& PInfo_SetMethod
) != 0)
1955 MONO_STRUCT_SETREF (info
, set
, property
->property
->set
?
1956 mono_method_get_object (domain
, property
->property
->set
, property
->klass
): NULL
);
1958 * There may be other methods defined for properties, though, it seems they are not exposed
1959 * in the reflection API
1964 ves_icall_get_event_info (MonoReflectionEvent
*event
, MonoEventInfo
*info
)
1966 MonoDomain
*domain
= mono_object_domain (event
);
1968 MONO_ARCH_SAVE_REGS
;
1970 info
->reflected_type
= mono_type_get_object (domain
, &event
->klass
->byval_arg
);
1971 info
->declaring_type
= mono_type_get_object (domain
, &event
->event
->parent
->byval_arg
);
1973 info
->name
= mono_string_new (domain
, event
->event
->name
);
1974 info
->attrs
= event
->event
->attrs
;
1975 info
->add_method
= event
->event
->add
? mono_method_get_object (domain
, event
->event
->add
, NULL
): NULL
;
1976 info
->remove_method
= event
->event
->remove
? mono_method_get_object (domain
, event
->event
->remove
, NULL
): NULL
;
1977 info
->raise_method
= event
->event
->raise
? mono_method_get_object (domain
, event
->event
->raise
, NULL
): NULL
;
1979 if (event
->event
->other
) {
1981 while (event
->event
->other
[n
])
1983 info
->other_methods
= mono_array_new (domain
, mono_defaults
.method_info_class
, n
);
1985 for (i
= 0; i
< n
; i
++)
1986 mono_array_setref (info
->other_methods
, i
, mono_method_get_object (domain
, event
->event
->other
[i
], NULL
));
1991 ves_icall_Type_GetInterfaces (MonoReflectionType
* type
)
1993 MonoDomain
*domain
= mono_object_domain (type
);
1995 GPtrArray
*ifaces
= NULL
;
1997 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2000 MonoGenericContext
*context
= NULL
;
2002 MONO_ARCH_SAVE_REGS
;
2004 if (class->generic_class
&& class->generic_class
->context
.class_inst
->is_open
) {
2005 context
= mono_class_get_context (class);
2006 class = class->generic_class
->container_class
;
2009 mono_class_setup_vtable (class);
2011 slots
= mono_bitset_new (class->max_interface_id
+ 1, 0);
2013 for (parent
= class; parent
; parent
= parent
->parent
) {
2014 GPtrArray
*tmp_ifaces
= mono_class_get_implemented_interfaces (parent
);
2016 for (i
= 0; i
< tmp_ifaces
->len
; ++i
) {
2017 MonoClass
*ic
= g_ptr_array_index (tmp_ifaces
, i
);
2019 if (mono_bitset_test (slots
, ic
->interface_id
))
2022 mono_bitset_set (slots
, ic
->interface_id
);
2024 ifaces
= g_ptr_array_new ();
2025 g_ptr_array_add (ifaces
, ic
);
2027 g_ptr_array_free (tmp_ifaces
, TRUE
);
2030 mono_bitset_free (slots
);
2033 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
2035 intf
= mono_array_new (domain
, mono_defaults
.monotype_class
, ifaces
->len
);
2036 for (i
= 0; i
< ifaces
->len
; ++i
) {
2037 MonoClass
*ic
= g_ptr_array_index (ifaces
, i
);
2038 MonoType
*ret
= &ic
->byval_arg
, *inflated
= NULL
;
2039 if (context
&& ic
->generic_class
&& ic
->generic_class
->context
.class_inst
->is_open
)
2040 inflated
= ret
= mono_class_inflate_generic_type (ret
, context
);
2042 mono_array_setref (intf
, i
, mono_type_get_object (domain
, ret
));
2044 mono_metadata_free_type (inflated
);
2046 g_ptr_array_free (ifaces
, TRUE
);
2052 ves_icall_Type_GetInterfaceMapData (MonoReflectionType
*type
, MonoReflectionType
*iface
, MonoArray
**targets
, MonoArray
**methods
)
2054 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2055 MonoClass
*iclass
= mono_class_from_mono_type (iface
->type
);
2056 MonoReflectionMethod
*member
;
2059 int i
= 0, len
, ioffset
;
2062 MONO_ARCH_SAVE_REGS
;
2064 mono_class_setup_vtable (class);
2066 /* type doesn't implement iface: the exception is thrown in managed code */
2067 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass
->interface_id
))
2070 len
= mono_class_num_methods (iclass
);
2071 ioffset
= mono_class_interface_offset (class, iclass
);
2072 domain
= mono_object_domain (type
);
2073 *targets
= mono_array_new (domain
, mono_defaults
.method_info_class
, len
);
2074 *methods
= mono_array_new (domain
, mono_defaults
.method_info_class
, len
);
2077 while ((method
= mono_class_get_methods (iclass
, &iter
))) {
2078 member
= mono_method_get_object (domain
, method
, iclass
);
2079 mono_array_setref (*methods
, i
, member
);
2080 member
= mono_method_get_object (domain
, class->vtable
[i
+ ioffset
], class);
2081 mono_array_setref (*targets
, i
, member
);
2088 ves_icall_Type_GetPacking (MonoReflectionType
*type
, guint32
*packing
, guint32
*size
)
2090 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2092 if (klass
->image
->dynamic
) {
2093 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)type
;
2094 *packing
= tb
->packing_size
;
2095 *size
= tb
->class_size
;
2097 mono_metadata_packing_from_typedef (klass
->image
, klass
->type_token
, packing
, size
);
2101 static MonoReflectionType
*
2102 ves_icall_MonoType_GetElementType (MonoReflectionType
*type
)
2104 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2106 MONO_ARCH_SAVE_REGS
;
2108 // GetElementType should only return a type for:
2109 // Array Pointer PassedByRef
2110 if (type
->type
->byref
)
2111 return mono_type_get_object (mono_object_domain (type
), &class->byval_arg
);
2112 else if (class->element_class
&& MONO_CLASS_IS_ARRAY (class))
2113 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2114 else if (class->element_class
&& type
->type
->type
== MONO_TYPE_PTR
)
2115 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2120 static MonoReflectionType
*
2121 ves_icall_get_type_parent (MonoReflectionType
*type
)
2123 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2125 MONO_ARCH_SAVE_REGS
;
2127 return class->parent
? mono_type_get_object (mono_object_domain (type
), &class->parent
->byval_arg
): NULL
;
2131 ves_icall_type_ispointer (MonoReflectionType
*type
)
2133 MONO_ARCH_SAVE_REGS
;
2135 return type
->type
->type
== MONO_TYPE_PTR
;
2139 ves_icall_type_isprimitive (MonoReflectionType
*type
)
2141 MONO_ARCH_SAVE_REGS
;
2143 return (!type
->type
->byref
&& (((type
->type
->type
>= MONO_TYPE_BOOLEAN
) && (type
->type
->type
<= MONO_TYPE_R8
)) || (type
->type
->type
== MONO_TYPE_I
) || (type
->type
->type
== MONO_TYPE_U
)));
2147 ves_icall_type_isbyref (MonoReflectionType
*type
)
2149 MONO_ARCH_SAVE_REGS
;
2151 return type
->type
->byref
;
2155 ves_icall_type_iscomobject (MonoReflectionType
*type
)
2157 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2158 MONO_ARCH_SAVE_REGS
;
2160 return (klass
&& klass
->is_com_object
);
2163 static MonoReflectionModule
*
2164 ves_icall_MonoType_get_Module (MonoReflectionType
*type
)
2166 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2168 MONO_ARCH_SAVE_REGS
;
2170 return mono_module_get_object (mono_object_domain (type
), class->image
);
2173 static MonoReflectionAssembly
*
2174 ves_icall_MonoType_get_Assembly (MonoReflectionType
*type
)
2176 MonoDomain
*domain
= mono_domain_get ();
2177 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2179 MONO_ARCH_SAVE_REGS
;
2181 return mono_assembly_get_object (domain
, class->image
->assembly
);
2184 static MonoReflectionType
*
2185 ves_icall_MonoType_get_DeclaringType (MonoReflectionType
*type
)
2187 MonoDomain
*domain
= mono_domain_get ();
2190 MONO_ARCH_SAVE_REGS
;
2192 if (type
->type
->byref
)
2194 if (type
->type
->type
== MONO_TYPE_VAR
)
2195 class = type
->type
->data
.generic_param
->owner
->owner
.klass
;
2196 else if (type
->type
->type
== MONO_TYPE_MVAR
)
2197 class = type
->type
->data
.generic_param
->owner
->owner
.method
->klass
;
2199 class = mono_class_from_mono_type (type
->type
)->nested_in
;
2201 return class ? mono_type_get_object (domain
, &class->byval_arg
) : NULL
;
2204 static MonoReflectionType
*
2205 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType
*type
)
2207 MonoDomain
*domain
= mono_domain_get ();
2208 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2210 MONO_ARCH_SAVE_REGS
;
2212 if (class->enumtype
&& mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
2213 return mono_type_get_object (domain
, mono_class_enum_basetype (class));
2214 else if (class->element_class
)
2215 return mono_type_get_object (domain
, &class->element_class
->byval_arg
);
2221 ves_icall_MonoType_get_Name (MonoReflectionType
*type
)
2223 MonoDomain
*domain
= mono_domain_get ();
2224 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2226 MONO_ARCH_SAVE_REGS
;
2228 if (type
->type
->byref
) {
2229 char *n
= g_strdup_printf ("%s&", class->name
);
2230 MonoString
*res
= mono_string_new (domain
, n
);
2236 return mono_string_new (domain
, class->name
);
2241 ves_icall_MonoType_get_Namespace (MonoReflectionType
*type
)
2243 MonoDomain
*domain
= mono_domain_get ();
2244 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2246 MONO_ARCH_SAVE_REGS
;
2248 while (class->nested_in
)
2249 class = class->nested_in
;
2251 if (class->name_space
[0] == '\0')
2254 return mono_string_new (domain
, class->name_space
);
2258 ves_icall_MonoType_GetArrayRank (MonoReflectionType
*type
)
2260 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2262 MONO_ARCH_SAVE_REGS
;
2268 ves_icall_MonoType_GetGenericArguments (MonoReflectionType
*type
)
2271 MonoClass
*klass
, *pklass
;
2273 MONO_ARCH_SAVE_REGS
;
2275 klass
= mono_class_from_mono_type (type
->type
);
2277 if (klass
->generic_container
) {
2278 MonoGenericContainer
*container
= klass
->generic_container
;
2279 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, container
->type_argc
);
2280 for (i
= 0; i
< container
->type_argc
; ++i
) {
2281 pklass
= mono_class_from_generic_parameter (&container
->type_params
[i
], klass
->image
, FALSE
);
2282 mono_array_setref (res
, i
, mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
));
2284 } else if (klass
->generic_class
) {
2285 MonoGenericInst
*inst
= klass
->generic_class
->context
.class_inst
;
2286 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, inst
->type_argc
);
2287 for (i
= 0; i
< inst
->type_argc
; ++i
)
2288 mono_array_setref (res
, i
, mono_type_get_object (mono_object_domain (type
), inst
->type_argv
[i
]));
2290 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, 0);
2296 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType
*type
)
2299 MONO_ARCH_SAVE_REGS
;
2301 if (type
->type
->byref
)
2304 klass
= mono_class_from_mono_type (type
->type
);
2306 return klass
->generic_container
!= NULL
;
2309 static MonoReflectionType
*
2310 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType
*type
)
2313 MONO_ARCH_SAVE_REGS
;
2315 if (type
->type
->byref
)
2318 klass
= mono_class_from_mono_type (type
->type
);
2319 if (klass
->generic_container
) {
2320 return type
; /* check this one */
2322 if (klass
->generic_class
) {
2323 MonoClass
*generic_class
= klass
->generic_class
->container_class
;
2325 if (generic_class
->wastypebuilder
&& generic_class
->reflection_info
)
2326 return generic_class
->reflection_info
;
2328 return mono_type_get_object (mono_object_domain (type
), &generic_class
->byval_arg
);
2333 static MonoReflectionType
*
2334 ves_icall_Type_MakeGenericType (MonoReflectionType
*type
, MonoArray
*type_array
)
2336 MonoType
*geninst
, **types
;
2339 MONO_ARCH_SAVE_REGS
;
2341 count
= mono_array_length (type_array
);
2342 types
= g_new0 (MonoType
*, count
);
2344 for (i
= 0; i
< count
; i
++) {
2345 MonoReflectionType
*t
= mono_array_get (type_array
, gpointer
, i
);
2346 types
[i
] = t
->type
;
2349 geninst
= mono_reflection_bind_generic_parameters (type
, count
, types
);
2354 return mono_type_get_object (mono_object_domain (type
), geninst
);
2358 ves_icall_Type_get_IsGenericInstance (MonoReflectionType
*type
)
2361 MONO_ARCH_SAVE_REGS
;
2363 if (type
->type
->byref
)
2366 klass
= mono_class_from_mono_type (type
->type
);
2367 return klass
->generic_class
!= NULL
;
2371 ves_icall_Type_get_IsGenericType (MonoReflectionType
*type
)
2374 MONO_ARCH_SAVE_REGS
;
2376 if (type
->type
->byref
)
2379 klass
= mono_class_from_mono_type (type
->type
);
2380 return klass
->generic_class
!= NULL
|| klass
->generic_container
!= NULL
;
2384 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType
*type
)
2386 MONO_ARCH_SAVE_REGS
;
2388 if (is_generic_parameter (type
->type
))
2389 return type
->type
->data
.generic_param
->num
;
2393 static GenericParameterAttributes
2394 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType
*type
)
2396 MONO_ARCH_SAVE_REGS
;
2397 g_assert (is_generic_parameter (type
->type
));
2398 return type
->type
->data
.generic_param
->flags
;
2402 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType
*type
)
2404 MonoGenericParam
*param
;
2410 MONO_ARCH_SAVE_REGS
;
2412 domain
= mono_object_domain (type
);
2413 param
= type
->type
->data
.generic_param
;
2414 for (count
= 0, ptr
= param
->constraints
; ptr
&& *ptr
; ptr
++, count
++)
2417 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
2418 for (i
= 0; i
< count
; i
++)
2419 mono_array_setref (res
, i
, mono_type_get_object (domain
, ¶m
->constraints
[i
]->byval_arg
));
2426 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType
*type
)
2428 MONO_ARCH_SAVE_REGS
;
2429 return is_generic_parameter (type
->type
);
2433 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder
*tb
)
2435 MONO_ARCH_SAVE_REGS
;
2436 return is_generic_parameter (tb
->type
.type
);
2440 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType
*enumtype
,
2441 MonoReflectionType
*t
)
2443 enumtype
->type
= t
->type
;
2446 static MonoReflectionType
*
2447 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass
*type
)
2449 MonoDynamicGenericClass
*gclass
;
2450 MonoReflectionType
*parent
= NULL
, *res
;
2456 MONO_ARCH_SAVE_REGS
;
2458 g_assert (type
->type
.type
->data
.generic_class
->is_dynamic
);
2459 gclass
= (MonoDynamicGenericClass
*) type
->type
.type
->data
.generic_class
;
2461 domain
= mono_object_domain (type
);
2462 klass
= mono_class_from_mono_type (type
->generic_type
->type
.type
);
2464 if (!klass
->generic_class
&& !klass
->generic_container
)
2467 parent
= type
->generic_type
->parent
;
2469 if (!parent
|| (parent
->type
->type
!= MONO_TYPE_GENERICINST
))
2472 inflated
= mono_class_inflate_generic_type (
2473 parent
->type
, mono_generic_class_get_context ((MonoGenericClass
*) gclass
));
2475 res
= mono_type_get_object (domain
, inflated
);
2476 mono_metadata_free_type (inflated
);
2481 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass
*type
)
2483 static MonoClass
*System_Reflection_MonoGenericClass
;
2484 MonoGenericClass
*gclass
;
2485 MonoReflectionTypeBuilder
*tb
= NULL
;
2486 MonoClass
*klass
= NULL
;
2491 MONO_ARCH_SAVE_REGS
;
2493 if (!System_Reflection_MonoGenericClass
) {
2494 System_Reflection_MonoGenericClass
= mono_class_from_name (
2495 mono_defaults
.corlib
, "System.Reflection", "MonoGenericClass");
2496 g_assert (System_Reflection_MonoGenericClass
);
2499 domain
= mono_object_domain (type
);
2501 gclass
= type
->type
.type
->data
.generic_class
;
2502 g_assert (gclass
->is_dynamic
);
2504 tb
= type
->generic_type
;
2505 icount
= tb
->interfaces
? mono_array_length (tb
->interfaces
) : 0;
2507 res
= mono_array_new (domain
, System_Reflection_MonoGenericClass
, icount
);
2509 for (i
= 0; i
< icount
; i
++) {
2510 MonoReflectionType
*iface
;
2514 iface
= mono_array_get (tb
->interfaces
, MonoReflectionType
*, i
);
2517 it
= &klass
->interfaces
[i
]->byval_arg
;
2519 it
= mono_class_inflate_generic_type (it
, mono_generic_class_get_context (gclass
));
2521 iface
= mono_type_get_object (domain
, it
);
2522 mono_array_setref (res
, i
, iface
);
2523 mono_metadata_free_type (it
);
2529 static MonoReflectionMethod
*
2530 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass
*type
,
2531 MonoReflectionMethod
* generic
)
2533 MonoGenericClass
*gclass
;
2534 MonoDynamicGenericClass
*dgclass
;
2538 MONO_ARCH_SAVE_REGS
;
2540 gclass
= type
->type
.type
->data
.generic_class
;
2541 g_assert (gclass
->is_dynamic
);
2543 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2545 domain
= mono_object_domain (type
);
2547 for (i
= 0; i
< dgclass
->count_methods
; i
++)
2548 if (generic
->method
->token
== dgclass
->methods
[i
]->token
)
2549 return mono_method_get_object (domain
, dgclass
->methods
[i
], NULL
);
2554 static MonoReflectionMethod
*
2555 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass
*type
,
2556 MonoReflectionMethod
* generic
)
2558 MonoGenericClass
*gclass
;
2559 MonoDynamicGenericClass
*dgclass
;
2563 MONO_ARCH_SAVE_REGS
;
2565 gclass
= type
->type
.type
->data
.generic_class
;
2566 g_assert (gclass
->is_dynamic
);
2568 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2570 domain
= mono_object_domain (type
);
2572 for (i
= 0; i
< dgclass
->count_ctors
; i
++)
2573 if (generic
->method
->token
== dgclass
->ctors
[i
]->token
)
2574 return mono_method_get_object (domain
, dgclass
->ctors
[i
], NULL
);
2580 static MonoReflectionField
*
2581 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass
*type
,
2582 MonoString
* generic_name
)
2584 MonoGenericClass
*gclass
;
2585 MonoDynamicGenericClass
*dgclass
;
2587 MonoClass
*refclass
;
2588 char *utf8_name
= mono_string_to_utf8 (generic_name
);
2591 MONO_ARCH_SAVE_REGS
;
2593 gclass
= type
->type
.type
->data
.generic_class
;
2594 g_assert (gclass
->is_dynamic
);
2596 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2598 refclass
= mono_class_from_mono_type (type
->type
.type
);
2600 domain
= mono_object_domain (type
);
2602 for (i
= 0; i
< dgclass
->count_fields
; i
++)
2603 if (strcmp (utf8_name
, mono_field_get_name (&dgclass
->fields
[i
])) == 0) {
2605 return mono_field_get_object (domain
, refclass
, &dgclass
->fields
[i
]);
2614 static MonoReflectionMethod
*
2615 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType
*type
,
2616 MonoReflectionMethod
* generic
)
2623 MONO_ARCH_SAVE_REGS
;
2625 domain
= ((MonoObject
*)type
)->vtable
->domain
;
2627 klass
= mono_class_from_mono_type (type
->type
);
2630 while ((method
= mono_class_get_methods (klass
, &iter
))) {
2631 if (method
->token
== generic
->method
->token
)
2632 return mono_method_get_object (domain
, method
, klass
);
2639 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass
*type
,
2640 MonoReflectionType
*reflected_type
)
2642 MonoGenericClass
*gclass
;
2643 MonoDynamicGenericClass
*dgclass
;
2645 MonoClass
*refclass
;
2649 MONO_ARCH_SAVE_REGS
;
2651 gclass
= type
->type
.type
->data
.generic_class
;
2652 g_assert (gclass
->is_dynamic
);
2653 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2655 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2657 domain
= mono_object_domain (type
);
2658 res
= mono_array_new (domain
, mono_defaults
.method_info_class
, dgclass
->count_methods
);
2660 for (i
= 0; i
< dgclass
->count_methods
; i
++)
2661 mono_array_setref (res
, i
, mono_method_get_object (domain
, dgclass
->methods
[i
], refclass
));
2667 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass
*type
,
2668 MonoReflectionType
*reflected_type
)
2670 static MonoClass
*System_Reflection_ConstructorInfo
;
2671 MonoGenericClass
*gclass
;
2672 MonoDynamicGenericClass
*dgclass
;
2674 MonoClass
*refclass
;
2678 MONO_ARCH_SAVE_REGS
;
2680 if (!System_Reflection_ConstructorInfo
)
2681 System_Reflection_ConstructorInfo
= mono_class_from_name (
2682 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
2684 gclass
= type
->type
.type
->data
.generic_class
;
2685 g_assert (gclass
->is_dynamic
);
2686 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2688 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2690 domain
= mono_object_domain (type
);
2691 res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, dgclass
->count_ctors
);
2693 for (i
= 0; i
< dgclass
->count_ctors
; i
++)
2694 mono_array_setref (res
, i
, mono_method_get_object (domain
, dgclass
->ctors
[i
], refclass
));
2700 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass
*type
,
2701 MonoReflectionType
*reflected_type
)
2703 MonoGenericClass
*gclass
;
2704 MonoDynamicGenericClass
*dgclass
;
2706 MonoClass
*refclass
;
2710 MONO_ARCH_SAVE_REGS
;
2712 gclass
= type
->type
.type
->data
.generic_class
;
2713 g_assert (gclass
->is_dynamic
);
2714 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2716 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2718 domain
= mono_object_domain (type
);
2719 res
= mono_array_new (domain
, mono_defaults
.field_info_class
, dgclass
->count_fields
);
2721 for (i
= 0; i
< dgclass
->count_fields
; i
++)
2722 mono_array_setref (res
, i
, mono_field_get_object (domain
, refclass
, &dgclass
->fields
[i
]));
2728 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass
*type
,
2729 MonoReflectionType
*reflected_type
)
2731 static MonoClass
*System_Reflection_PropertyInfo
;
2732 MonoGenericClass
*gclass
;
2733 MonoDynamicGenericClass
*dgclass
;
2735 MonoClass
*refclass
;
2739 MONO_ARCH_SAVE_REGS
;
2741 if (!System_Reflection_PropertyInfo
)
2742 System_Reflection_PropertyInfo
= mono_class_from_name (
2743 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
2745 gclass
= type
->type
.type
->data
.generic_class
;
2746 g_assert (gclass
->is_dynamic
);
2747 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2749 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2751 domain
= mono_object_domain (type
);
2752 res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, dgclass
->count_properties
);
2754 for (i
= 0; i
< dgclass
->count_properties
; i
++)
2755 mono_array_setref (res
, i
, mono_property_get_object (domain
, refclass
, &dgclass
->properties
[i
]));
2761 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass
*type
,
2762 MonoReflectionType
*reflected_type
)
2764 static MonoClass
*System_Reflection_EventInfo
;
2765 MonoGenericClass
*gclass
;
2766 MonoDynamicGenericClass
*dgclass
;
2768 MonoClass
*refclass
;
2772 MONO_ARCH_SAVE_REGS
;
2774 if (!System_Reflection_EventInfo
)
2775 System_Reflection_EventInfo
= mono_class_from_name (
2776 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
2778 gclass
= type
->type
.type
->data
.generic_class
;
2779 g_assert (gclass
->is_dynamic
);
2780 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2782 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2784 domain
= mono_object_domain (type
);
2785 res
= mono_array_new (domain
, System_Reflection_EventInfo
, dgclass
->count_events
);
2787 for (i
= 0; i
< dgclass
->count_events
; i
++)
2788 mono_array_setref (res
, i
, mono_event_get_object (domain
, refclass
, &dgclass
->events
[i
]));
2793 static MonoReflectionType
*
2794 ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass
*type
,
2795 MonoReflectionType
*target
)
2799 MonoReflectionType
*res
;
2801 MONO_ARCH_SAVE_REGS
;
2803 gklass
= mono_class_from_mono_type (type
->type
.type
);
2804 res_type
= mono_class_inflate_generic_type (target
->type
, mono_class_get_context (gklass
));
2805 res
= mono_type_get_object (mono_object_domain (type
), res_type
);
2806 mono_metadata_free_type (res_type
);
2810 static MonoReflectionMethod
*
2811 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType
*type
)
2816 MONO_ARCH_SAVE_REGS
;
2818 if (type
->type
->byref
|| type
->type
->type
!= MONO_TYPE_MVAR
)
2821 method
= type
->type
->data
.generic_param
->owner
->owner
.method
;
2823 klass
= mono_class_from_mono_type (type
->type
);
2824 return mono_method_get_object (mono_object_domain (type
), method
, klass
);
2827 static MonoReflectionDllImportAttribute
*
2828 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod
*method
)
2830 static MonoClass
*DllImportAttributeClass
= NULL
;
2831 MonoDomain
*domain
= mono_domain_get ();
2832 MonoReflectionDllImportAttribute
*attr
;
2833 MonoImage
*image
= method
->klass
->image
;
2834 MonoMethodPInvoke
*piinfo
= (MonoMethodPInvoke
*)method
;
2835 MonoTableInfo
*tables
= image
->tables
;
2836 MonoTableInfo
*im
= &tables
[MONO_TABLE_IMPLMAP
];
2837 MonoTableInfo
*mr
= &tables
[MONO_TABLE_MODULEREF
];
2838 guint32 im_cols
[MONO_IMPLMAP_SIZE
];
2839 guint32 scope_token
;
2840 const char *import
= NULL
;
2841 const char *scope
= NULL
;
2844 if (!method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
)
2847 if (!DllImportAttributeClass
) {
2848 DllImportAttributeClass
=
2849 mono_class_from_name (mono_defaults
.corlib
,
2850 "System.Runtime.InteropServices", "DllImportAttribute");
2851 g_assert (DllImportAttributeClass
);
2854 if (method
->klass
->image
->dynamic
) {
2855 MonoReflectionMethodAux
*method_aux
=
2856 g_hash_table_lookup (
2857 ((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
2859 import
= method_aux
->dllentry
;
2860 scope
= method_aux
->dll
;
2864 if (piinfo
->implmap_idx
) {
2865 mono_metadata_decode_row (im
, piinfo
->implmap_idx
- 1, im_cols
, MONO_IMPLMAP_SIZE
);
2867 piinfo
->piflags
= im_cols
[MONO_IMPLMAP_FLAGS
];
2868 import
= mono_metadata_string_heap (image
, im_cols
[MONO_IMPLMAP_NAME
]);
2869 scope_token
= mono_metadata_decode_row_col (mr
, im_cols
[MONO_IMPLMAP_SCOPE
] - 1, MONO_MODULEREF_NAME
);
2870 scope
= mono_metadata_string_heap (image
, scope_token
);
2873 flags
= piinfo
->piflags
;
2875 attr
= (MonoReflectionDllImportAttribute
*)mono_object_new (domain
, DllImportAttributeClass
);
2877 MONO_OBJECT_SETREF (attr
, dll
, mono_string_new (domain
, scope
));
2878 MONO_OBJECT_SETREF (attr
, entry_point
, mono_string_new (domain
, import
));
2879 attr
->call_conv
= (flags
& 0x700) >> 8;
2880 attr
->charset
= ((flags
& 0x6) >> 1) + 1;
2881 if (attr
->charset
== 1)
2883 attr
->exact_spelling
= (flags
& 0x1) != 0;
2884 attr
->set_last_error
= (flags
& 0x40) != 0;
2885 attr
->best_fit_mapping
= (flags
& 0x30) == 0x10;
2886 attr
->throw_on_unmappable
= (flags
& 0x3000) == 0x1000;
2887 attr
->preserve_sig
= FALSE
;
2892 static MonoReflectionMethod
*
2893 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod
*method
)
2895 MonoMethodInflated
*imethod
;
2898 MONO_ARCH_SAVE_REGS
;
2900 if (method
->method
->is_generic
)
2903 if (!method
->method
->is_inflated
)
2906 imethod
= (MonoMethodInflated
*) method
->method
;
2908 result
= imethod
->declaring
;
2909 /* Not a generic method. */
2910 if (!result
->is_generic
)
2913 if (method
->method
->klass
->image
->dynamic
) {
2914 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->method
->klass
->image
;
2915 MonoReflectionMethod
*res
;
2918 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2919 * the dynamic case as well ?
2921 mono_loader_lock ();
2922 res
= mono_g_hash_table_lookup (image
->generic_def_objects
, imethod
);
2923 mono_loader_unlock ();
2929 if (imethod
->context
.class_inst
) {
2930 MonoClass
*klass
= ((MonoMethod
*) imethod
)->klass
;
2931 result
= mono_class_inflate_generic_method_full (result
, klass
, mono_class_get_context (klass
));
2934 return mono_method_get_object (mono_object_domain (method
), result
, NULL
);
2938 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod
*method
)
2940 MONO_ARCH_SAVE_REGS
;
2942 return mono_method_signature (method
->method
)->generic_param_count
!= 0;
2946 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod
*method
)
2948 MONO_ARCH_SAVE_REGS
;
2950 return method
->method
->is_generic
;
2954 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod
*method
)
2959 MONO_ARCH_SAVE_REGS
;
2961 domain
= mono_object_domain (method
);
2963 if (method
->method
->is_inflated
) {
2964 MonoGenericInst
*inst
= mono_method_get_context (method
->method
)->method_inst
;
2967 count
= inst
->type_argc
;
2968 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2970 for (i
= 0; i
< count
; i
++)
2971 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2977 count
= mono_method_signature (method
->method
)->generic_param_count
;
2978 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2980 for (i
= 0; i
< count
; i
++) {
2981 MonoGenericContainer
*container
= mono_method_get_generic_container (method
->method
);
2982 MonoGenericParam
*param
= &container
->type_params
[i
];
2983 MonoClass
*pklass
= mono_class_from_generic_parameter (
2984 param
, method
->method
->klass
->image
, TRUE
);
2985 mono_array_setref (res
, i
,
2986 mono_type_get_object (domain
, &pklass
->byval_arg
));
2993 ensure_reflection_security (void)
2995 MonoMethod
*m
= mono_method_get_last_managed ();
2999 g_print ("method %s.%s.%s in image %s\n",
3000 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
3003 /* We stop at the first method which is not in
3004 System.Reflection or which is not in a platform
3006 if (strcmp (m
->klass
->name_space
, "System.Reflection") != 0 ||
3007 !mono_security_core_clr_is_platform_image (m
->klass
->image
)) {
3008 /* If the method is transparent we throw an exception. */
3009 if (mono_security_core_clr_method_level (m
, TRUE
) == MONO_SECURITY_CORE_CLR_TRANSPARENT
) {
3010 MonoException
*ex
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System", "MethodAccessException", "Reflection called from transparent code");
3012 mono_raise_exception (ex
);
3017 mono_stack_walk_no_il (get_caller
, &m
);
3022 can_call_generic_shared_method_for_class (MonoDomain
*domain
, MonoMethod
*method
, MonoClass
*class)
3024 MonoClass
*method_class
;
3026 if (!mono_method_is_generic_sharable_impl (method
, FALSE
))
3029 method
= mono_method_get_declaring_generic_method (method
);
3030 method_class
= method
->klass
;
3031 g_assert (!method_class
->generic_class
);
3033 if (!mono_domain_lookup_shared_generic (domain
, method
))
3037 if (class->generic_class
)
3038 class = class->generic_class
->container_class
;
3039 if (method_class
== class)
3041 class = class->parent
;
3048 ves_icall_InternalInvoke (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoException
**exc
)
3051 * Invoke from reflection is supposed to always be a virtual call (the API
3052 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3053 * greater flexibility.
3055 MonoMethod
*m
= method
->method
;
3059 MONO_ARCH_SAVE_REGS
;
3063 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
&&
3064 mono_security_core_clr_method_level (m
, TRUE
) == MONO_SECURITY_CORE_CLR_CRITICAL
)
3065 ensure_reflection_security ();
3067 if (!(m
->flags
& METHOD_ATTRIBUTE_STATIC
)) {
3069 if (!mono_object_isinst (this, m
->klass
) &&
3070 !can_call_generic_shared_method_for_class (this->vtable
->domain
, m
, this->vtable
->klass
)) {
3071 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Object does not match target type.");
3074 m
= mono_object_get_virtual_method (this, m
);
3075 /* must pass the pointer to the value for valuetype methods */
3076 if (m
->klass
->valuetype
)
3077 obj
= mono_object_unbox (this);
3078 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
3079 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target.");
3084 pcount
= params
? mono_array_length (params
): 0;
3085 if (pcount
!= mono_method_signature (m
)->param_count
) {
3086 *exc
= mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException");
3090 if ((m
->klass
->flags
& TYPE_ATTRIBUTE_ABSTRACT
) && !strcmp (m
->name
, ".ctor") && !this) {
3091 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
3095 if (m
->klass
->image
->assembly
->ref_only
) {
3096 *exc
= mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
3100 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
3102 mono_array_size_t
*lengths
;
3103 mono_array_size_t
*lower_bounds
;
3104 pcount
= mono_array_length (params
);
3105 lengths
= alloca (sizeof (mono_array_size_t
) * pcount
);
3106 for (i
= 0; i
< pcount
; ++i
)
3107 lengths
[i
] = *(mono_array_size_t
*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
3109 if (m
->klass
->rank
== pcount
) {
3110 /* Only lengths provided. */
3111 lower_bounds
= NULL
;
3113 g_assert (pcount
== (m
->klass
->rank
* 2));
3114 /* lower bounds are first. */
3115 lower_bounds
= lengths
;
3116 lengths
+= m
->klass
->rank
;
3119 return (MonoObject
*)mono_array_new_full (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
);
3121 return mono_runtime_invoke_array (m
, obj
, params
, NULL
);
3125 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoArray
**outArgs
)
3127 MonoDomain
*domain
= mono_object_domain (method
);
3128 MonoMethod
*m
= method
->method
;
3129 MonoMethodSignature
*sig
= mono_method_signature (m
);
3130 MonoArray
*out_args
;
3132 int i
, j
, outarg_count
= 0;
3134 MONO_ARCH_SAVE_REGS
;
3136 if (m
->klass
== mono_defaults
.object_class
) {
3138 if (!strcmp (m
->name
, "FieldGetter")) {
3139 MonoClass
*k
= this->vtable
->klass
;
3143 /* If this is a proxy, then it must be a CBO */
3144 if (k
== mono_defaults
.transparent_proxy_class
) {
3145 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
3146 this = tp
->rp
->unwrapped_server
;
3148 k
= this->vtable
->klass
;
3151 name
= mono_array_get (params
, MonoString
*, 1);
3152 str
= mono_string_to_utf8 (name
);
3155 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3157 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3158 if (field_klass
->valuetype
)
3159 result
= mono_value_box (domain
, field_klass
, (char *)this + field
->offset
);
3161 result
= *((gpointer
*)((char *)this + field
->offset
));
3163 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 1);
3164 *outArgs
= out_args
;
3165 mono_array_setref (out_args
, 0, result
);
3173 g_assert_not_reached ();
3175 } else if (!strcmp (m
->name
, "FieldSetter")) {
3176 MonoClass
*k
= this->vtable
->klass
;
3182 /* If this is a proxy, then it must be a CBO */
3183 if (k
== mono_defaults
.transparent_proxy_class
) {
3184 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
3185 this = tp
->rp
->unwrapped_server
;
3187 k
= this->vtable
->klass
;
3190 name
= mono_array_get (params
, MonoString
*, 1);
3191 str
= mono_string_to_utf8 (name
);
3194 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3196 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3197 MonoObject
*val
= mono_array_get (params
, gpointer
, 2);
3199 if (field_klass
->valuetype
) {
3200 size
= mono_type_size (field
->type
, &align
);
3202 mono_gc_wbarrier_value_copy ((char *)this + field
->offset
, (char*)val
+ sizeof (MonoObject
), 1, field_klass
);
3204 memcpy ((char *)this + field
->offset
,
3205 ((char *)val
) + sizeof (MonoObject
), size
);
3207 mono_gc_wbarrier_set_field (this, (char*)this + field
->offset
, val
);
3210 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 0);
3211 *outArgs
= out_args
;
3221 g_assert_not_reached ();
3226 for (i
= 0; i
< mono_array_length (params
); i
++) {
3227 if (sig
->params
[i
]->byref
)
3231 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, outarg_count
);
3233 /* handle constructors only for objects already allocated */
3234 if (!strcmp (method
->method
->name
, ".ctor"))
3237 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3238 g_assert (!method
->method
->klass
->valuetype
);
3239 result
= mono_runtime_invoke_array (method
->method
, this, params
, NULL
);
3241 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
3242 if (sig
->params
[i
]->byref
) {
3244 arg
= mono_array_get (params
, gpointer
, i
);
3245 mono_array_setref (out_args
, j
, arg
);
3250 *outArgs
= out_args
;
3256 read_enum_value (char *mem
, int type
)
3260 return *(guint8
*)mem
;
3262 return *(gint8
*)mem
;
3264 return *(guint16
*)mem
;
3266 return *(gint16
*)mem
;
3268 return *(guint32
*)mem
;
3270 return *(gint32
*)mem
;
3272 return *(guint64
*)mem
;
3274 return *(gint64
*)mem
;
3276 g_assert_not_reached ();
3282 write_enum_value (char *mem
, int type
, guint64 value
)
3286 case MONO_TYPE_I1
: {
3287 guint8
*p
= (guint8
*)mem
;
3292 case MONO_TYPE_I2
: {
3293 guint16
*p
= (void*)mem
;
3298 case MONO_TYPE_I4
: {
3299 guint32
*p
= (void*)mem
;
3304 case MONO_TYPE_I8
: {
3305 guint64
*p
= (void*)mem
;
3310 g_assert_not_reached ();
3316 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, MonoObject
*value
)
3319 MonoClass
*enumc
, *objc
;
3323 MONO_ARCH_SAVE_REGS
;
3325 MONO_CHECK_ARG_NULL (enumType
);
3326 MONO_CHECK_ARG_NULL (value
);
3328 domain
= mono_object_domain (enumType
);
3329 enumc
= mono_class_from_mono_type (enumType
->type
);
3330 objc
= value
->vtable
->klass
;
3332 if (!enumc
->enumtype
)
3333 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3334 if (!((objc
->enumtype
) || (objc
->byval_arg
.type
>= MONO_TYPE_I1
&& objc
->byval_arg
.type
<= MONO_TYPE_U8
)))
3335 mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
3337 res
= mono_object_new (domain
, enumc
);
3338 val
= read_enum_value ((char *)value
+ sizeof (MonoObject
), objc
->enumtype
? mono_class_enum_basetype (objc
)->type
: objc
->byval_arg
.type
);
3339 write_enum_value ((char *)res
+ sizeof (MonoObject
), mono_class_enum_basetype (enumc
)->type
, val
);
3345 ves_icall_System_Enum_get_value (MonoObject
*this)
3353 MONO_ARCH_SAVE_REGS
;
3358 g_assert (this->vtable
->klass
->enumtype
);
3360 enumc
= mono_class_from_mono_type (mono_class_enum_basetype (this->vtable
->klass
));
3361 res
= mono_object_new (mono_object_domain (this), enumc
);
3362 dst
= (char *)res
+ sizeof (MonoObject
);
3363 src
= (char *)this + sizeof (MonoObject
);
3364 size
= mono_class_value_size (enumc
, NULL
);
3366 memcpy (dst
, src
, size
);
3371 static MonoReflectionType
*
3372 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3374 MONO_ARCH_SAVE_REGS
;
3376 return mono_type_get_object (mono_object_domain (type
), mono_class_enum_basetype (mono_class_from_mono_type (type
->type
)));
3380 ves_icall_System_Enum_get_hashcode (MonoObject
*this)
3382 gpointer data
= (char *)this + sizeof (MonoObject
);
3383 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3384 g_assert (basetype
);
3386 switch (basetype
->type
) {
3388 return *((gint8
*)data
);
3390 return *((guint8
*)data
);
3391 case MONO_TYPE_CHAR
:
3393 return *((guint16
*)data
);
3396 return *((gint16
*)data
);
3398 return *((guint32
*)data
);
3400 return *((gint32
*)data
);
3402 case MONO_TYPE_I8
: {
3403 gint64 value
= *((gint64
*)data
);
3404 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3407 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3413 ves_icall_get_enum_info (MonoReflectionType
*type
, MonoEnumInfo
*info
)
3415 MonoDomain
*domain
= mono_object_domain (type
);
3416 MonoClass
*enumc
= mono_class_from_mono_type (type
->type
);
3417 guint j
= 0, nvalues
, crow
;
3419 MonoClassField
*field
;
3421 MONO_ARCH_SAVE_REGS
;
3423 info
->utype
= mono_type_get_object (domain
, mono_class_enum_basetype (enumc
));
3424 nvalues
= mono_class_num_fields (enumc
) ? mono_class_num_fields (enumc
) - 1 : 0;
3425 info
->names
= mono_array_new (domain
, mono_defaults
.string_class
, nvalues
);
3426 info
->values
= mono_array_new (domain
, enumc
, nvalues
);
3430 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3433 MonoTypeEnum def_type
;
3435 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3437 if (mono_field_is_deleted (field
))
3439 mono_array_setref (info
->names
, j
, mono_string_new (domain
, mono_field_get_name (field
)));
3441 p
= mono_class_get_field_default_value (field
, &def_type
);
3442 len
= mono_metadata_decode_blob_size (p
, &p
);
3443 switch (mono_class_enum_basetype (enumc
)->type
) {
3446 mono_array_set (info
->values
, gchar
, j
, *p
);
3448 case MONO_TYPE_CHAR
:
3451 mono_array_set (info
->values
, gint16
, j
, read16 (p
));
3455 mono_array_set (info
->values
, gint32
, j
, read32 (p
));
3459 mono_array_set (info
->values
, gint64
, j
, read64 (p
));
3462 g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc
)->type
);
3469 BFLAGS_IgnoreCase
= 1,
3470 BFLAGS_DeclaredOnly
= 2,
3471 BFLAGS_Instance
= 4,
3473 BFLAGS_Public
= 0x10,
3474 BFLAGS_NonPublic
= 0x20,
3475 BFLAGS_FlattenHierarchy
= 0x40,
3476 BFLAGS_InvokeMethod
= 0x100,
3477 BFLAGS_CreateInstance
= 0x200,
3478 BFLAGS_GetField
= 0x400,
3479 BFLAGS_SetField
= 0x800,
3480 BFLAGS_GetProperty
= 0x1000,
3481 BFLAGS_SetProperty
= 0x2000,
3482 BFLAGS_ExactBinding
= 0x10000,
3483 BFLAGS_SuppressChangeType
= 0x20000,
3484 BFLAGS_OptionalParamBinding
= 0x40000
3487 static MonoReflectionField
*
3488 ves_icall_Type_GetField (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3491 MonoClass
*startklass
, *klass
;
3493 MonoClassField
*field
;
3496 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3497 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3498 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3500 MONO_ARCH_SAVE_REGS
;
3503 mono_raise_exception (mono_get_exception_argument_null ("name"));
3504 if (type
->type
->byref
)
3507 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? g_strcasecmp
: strcmp
;
3510 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3511 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3514 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3517 if (field
->type
== NULL
)
3519 if (mono_field_is_deleted (field
))
3521 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3522 if (bflags
& BFLAGS_Public
)
3524 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3525 if (bflags
& BFLAGS_NonPublic
) {
3532 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3533 if (bflags
& BFLAGS_Static
)
3534 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3537 if (bflags
& BFLAGS_Instance
)
3544 utf8_name
= mono_string_to_utf8 (name
);
3546 if (compare_func (mono_field_get_name (field
), utf8_name
)) {
3552 return mono_field_get_object (domain
, klass
, field
);
3554 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3561 ves_icall_Type_GetFields_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3564 MonoClass
*startklass
, *klass
, *refklass
;
3569 MonoClassField
*field
;
3571 MONO_ARCH_SAVE_REGS
;
3573 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3574 if (type
->type
->byref
)
3575 return mono_array_new (domain
, mono_defaults
.field_info_class
, 0);
3576 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3577 refklass
= mono_class_from_mono_type (reftype
->type
);
3581 res
= mono_array_new (domain
, mono_defaults
.field_info_class
, len
);
3583 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3584 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3587 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3589 if (mono_field_is_deleted (field
))
3591 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3592 if (bflags
& BFLAGS_Public
)
3594 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3595 if (bflags
& BFLAGS_NonPublic
) {
3602 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3603 if (bflags
& BFLAGS_Static
)
3604 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3607 if (bflags
& BFLAGS_Instance
)
3613 member
= (MonoObject
*)mono_field_get_object (domain
, refklass
, field
);
3615 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.field_info_class
, len
* 2);
3616 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3620 mono_array_setref (res
, i
, member
);
3623 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3626 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.field_info_class
, i
);
3627 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3630 * Better solution for the new GC.
3631 * res->max_length = i;
3638 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3640 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3641 case METHOD_ATTRIBUTE_ASSEM
:
3642 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3643 case METHOD_ATTRIBUTE_PRIVATE
:
3645 case METHOD_ATTRIBUTE_PUBLIC
:
3653 ves_icall_Type_GetMethodsByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3655 static MonoClass
*MethodInfo_array
;
3657 MonoClass
*startklass
, *klass
, *refklass
;
3662 int i
, len
, match
, nslots
;
3663 guint32 method_slots_default
[8];
3664 guint32
*method_slots
;
3665 gchar
*mname
= NULL
;
3666 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3667 MonoVTable
*array_vtable
;
3669 MONO_ARCH_SAVE_REGS
;
3671 if (!MethodInfo_array
) {
3672 MonoClass
*klass
= mono_array_class_get (mono_defaults
.method_info_class
, 1);
3673 mono_memory_barrier ();
3674 MethodInfo_array
= klass
;
3677 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3678 array_vtable
= mono_class_vtable (domain
, MethodInfo_array
);
3679 if (type
->type
->byref
)
3680 return mono_array_new_specific (array_vtable
, 0);
3681 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3682 refklass
= mono_class_from_mono_type (reftype
->type
);
3685 mname
= mono_string_to_utf8 (name
);
3686 compare_func
= (ignore_case
) ? g_strcasecmp
: strcmp
;
3689 /* An optimization for calls made from Delegate:CreateDelegate () */
3690 if (klass
->delegate
&& mname
&& !strcmp (mname
, "Invoke") && (bflags
== (BFLAGS_Public
| BFLAGS_Static
| BFLAGS_Instance
))) {
3691 method
= mono_get_delegate_invoke (klass
);
3693 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3695 res
= mono_array_new_specific (array_vtable
, 1);
3696 mono_array_setref (res
, 0, member
);
3700 mono_class_setup_vtable (klass
);
3702 if (is_generic_parameter (type
->type
))
3703 nslots
= klass
->parent
->vtable_size
;
3705 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : klass
->vtable_size
;
3706 if (nslots
>= sizeof (method_slots_default
) * 8) {
3707 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3709 method_slots
= method_slots_default
;
3710 memset (method_slots
, 0, sizeof (method_slots_default
));
3714 res
= mono_array_new_specific (array_vtable
, len
);
3716 mono_class_setup_vtable (klass
);
3717 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3718 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3721 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3723 if (method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3725 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3726 if (bflags
& BFLAGS_Public
)
3728 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3734 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3735 if (bflags
& BFLAGS_Static
)
3736 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3739 if (bflags
& BFLAGS_Instance
)
3747 if (compare_func (mname
, method
->name
))
3752 if (method
->slot
!= -1) {
3753 g_assert (method
->slot
< nslots
);
3754 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3756 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3759 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3762 MonoArray
*new_res
= mono_array_new_specific (array_vtable
, len
* 2);
3763 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3767 mono_array_setref (res
, i
, member
);
3770 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3774 if (method_slots
!= method_slots_default
)
3775 g_free (method_slots
);
3777 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.method_info_class
, i
);
3778 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3781 * Better solution for the new GC.
3782 * res->max_length = i;
3789 ves_icall_Type_GetConstructors_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3792 static MonoClass
*System_Reflection_ConstructorInfo
;
3793 MonoClass
*startklass
, *klass
, *refklass
;
3798 gpointer iter
= NULL
;
3800 MONO_ARCH_SAVE_REGS
;
3802 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3803 if (type
->type
->byref
)
3804 return mono_array_new (domain
, mono_defaults
.method_info_class
, 0);
3805 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3806 refklass
= mono_class_from_mono_type (reftype
->type
);
3808 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3809 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3811 if (!System_Reflection_ConstructorInfo
)
3812 System_Reflection_ConstructorInfo
= mono_class_from_name (
3813 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
3817 res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, len
);
3819 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3821 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
3823 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3824 if (bflags
& BFLAGS_Public
)
3827 if (bflags
& BFLAGS_NonPublic
)
3833 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3834 if (bflags
& BFLAGS_Static
)
3835 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3838 if (bflags
& BFLAGS_Instance
)
3844 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3847 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, len
* 2);
3848 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3852 mono_array_setref (res
, i
, member
);
3856 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, i
);
3857 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3860 * Better solution for the new GC.
3861 * res->max_length = i;
3868 property_hash (gconstpointer data
)
3870 MonoProperty
*prop
= (MonoProperty
*)data
;
3872 return g_str_hash (prop
->name
);
3876 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
3878 // Properties are hide-by-name-and-signature
3879 if (!g_str_equal (prop1
->name
, prop2
->name
))
3882 if (prop1
->get
&& prop2
->get
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->get
), mono_method_signature (prop2
->get
)))
3884 if (prop1
->set
&& prop2
->set
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->set
), mono_method_signature (prop2
->set
)))
3890 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
3895 return method_nonpublic (accessor
, start_klass
);
3899 ves_icall_Type_GetPropertiesByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3902 static MonoClass
*System_Reflection_PropertyInfo
;
3903 MonoClass
*startklass
, *klass
;
3910 gchar
*propname
= NULL
;
3911 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3913 GHashTable
*properties
;
3915 MONO_ARCH_SAVE_REGS
;
3917 if (!System_Reflection_PropertyInfo
)
3918 System_Reflection_PropertyInfo
= mono_class_from_name (
3919 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
3921 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3922 if (type
->type
->byref
)
3923 return mono_array_new (domain
, System_Reflection_PropertyInfo
, 0);
3924 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3926 propname
= mono_string_to_utf8 (name
);
3927 compare_func
= (ignore_case
) ? g_strcasecmp
: strcmp
;
3930 mono_class_setup_vtable (klass
);
3932 properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
3935 res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, len
);
3937 mono_class_setup_vtable (klass
);
3938 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3939 g_hash_table_destroy (properties
);
3942 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3946 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
3952 flags
= method
->flags
;
3955 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
3956 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
3957 if (bflags
& BFLAGS_Public
)
3959 } else if (bflags
& BFLAGS_NonPublic
) {
3960 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
3961 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
3968 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
3969 if (bflags
& BFLAGS_Static
)
3970 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3973 if (bflags
& BFLAGS_Instance
)
3982 if (compare_func (propname
, prop
->name
))
3986 if (g_hash_table_lookup (properties
, prop
))
3990 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, len
* 2);
3991 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3995 mono_array_setref (res
, i
, mono_property_get_object (domain
, startklass
, prop
));
3998 g_hash_table_insert (properties
, prop
, prop
);
4000 if ((!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
)))
4003 g_hash_table_destroy (properties
);
4006 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, i
);
4007 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
4010 * Better solution for the new GC.
4011 * res->max_length = i;
4017 static MonoReflectionEvent
*
4018 ves_icall_MonoType_GetEvent (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
4021 MonoClass
*klass
, *startklass
;
4027 MONO_ARCH_SAVE_REGS
;
4029 event_name
= mono_string_to_utf8 (name
);
4030 if (type
->type
->byref
)
4032 klass
= startklass
= mono_class_from_mono_type (type
->type
);
4033 domain
= mono_object_domain (type
);
4036 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4037 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4040 while ((event
= mono_class_get_events (klass
, &iter
))) {
4041 if (strcmp (event
->name
, event_name
))
4044 method
= event
->add
;
4046 method
= event
->remove
;
4048 method
= event
->raise
;
4050 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
4051 if (!(bflags
& BFLAGS_Public
))
4054 if (!(bflags
& BFLAGS_NonPublic
))
4056 if ((klass
!= startklass
) && (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PRIVATE
)
4061 if (!(bflags
& BFLAGS_NonPublic
))
4064 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
4065 if (!(bflags
& BFLAGS_Static
))
4067 if (!(bflags
& BFLAGS_FlattenHierarchy
) && (klass
!= startklass
))
4070 if (!(bflags
& BFLAGS_Instance
))
4074 g_free (event_name
);
4075 return mono_event_get_object (domain
, startklass
, event
);
4078 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4081 g_free (event_name
);
4086 ves_icall_Type_GetEvents_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
4089 static MonoClass
*System_Reflection_EventInfo
;
4090 MonoClass
*startklass
, *klass
;
4097 MONO_ARCH_SAVE_REGS
;
4099 if (!System_Reflection_EventInfo
)
4100 System_Reflection_EventInfo
= mono_class_from_name (
4101 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
4103 domain
= mono_object_domain (type
);
4104 if (type
->type
->byref
)
4105 return mono_array_new (domain
, System_Reflection_EventInfo
, 0);
4106 klass
= startklass
= mono_class_from_mono_type (type
->type
);
4110 res
= mono_array_new (domain
, System_Reflection_EventInfo
, len
);
4112 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4113 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4116 while ((event
= mono_class_get_events (klass
, &iter
))) {
4118 method
= event
->add
;
4120 method
= event
->remove
;
4122 method
= event
->raise
;
4124 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
4125 if (bflags
& BFLAGS_Public
)
4127 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
4128 if (bflags
& BFLAGS_NonPublic
)
4133 if (bflags
& BFLAGS_NonPublic
)
4139 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
4140 if (bflags
& BFLAGS_Static
)
4141 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
4144 if (bflags
& BFLAGS_Instance
)
4149 if (bflags
& BFLAGS_Instance
)
4155 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_EventInfo
, len
* 2);
4156 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
4160 mono_array_setref (res
, i
, mono_event_get_object (domain
, startklass
, event
));
4163 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4166 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_EventInfo
, i
);
4167 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
4170 * Better solution for the new GC.
4171 * res->max_length = i;
4177 static MonoReflectionType
*
4178 ves_icall_Type_GetNestedType (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
4186 MONO_ARCH_SAVE_REGS
;
4188 domain
= ((MonoObject
*)type
)->vtable
->domain
;
4189 if (type
->type
->byref
)
4191 klass
= mono_class_from_mono_type (type
->type
);
4192 str
= mono_string_to_utf8 (name
);
4195 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4196 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4199 * If a nested type is generic, return its generic type definition.
4200 * Note that this means that the return value is essentially a
4201 * nested type of the generic type definition of @klass.
4203 * A note in MSDN claims that a generic type definition can have
4204 * nested types that aren't generic. In any case, the container of that
4205 * nested type would be the generic type definition.
4207 if (klass
->generic_class
)
4208 klass
= klass
->generic_class
->container_class
;
4211 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4213 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4214 if (bflags
& BFLAGS_Public
)
4217 if (bflags
& BFLAGS_NonPublic
)
4222 if (strcmp (nested
->name
, str
) == 0){
4224 return mono_type_get_object (domain
, &nested
->byval_arg
);
4227 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4234 ves_icall_Type_GetNestedTypes (MonoReflectionType
*type
, guint32 bflags
)
4244 MONO_ARCH_SAVE_REGS
;
4246 domain
= ((MonoObject
*)type
)->vtable
->domain
;
4247 if (type
->type
->byref
)
4248 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
4249 klass
= mono_class_from_mono_type (type
->type
);
4250 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4251 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4254 * If a nested type is generic, return its generic type definition.
4255 * Note that this means that the return value is essentially the set
4256 * of nested types of the generic type definition of @klass.
4258 * A note in MSDN claims that a generic type definition can have
4259 * nested types that aren't generic. In any case, the container of that
4260 * nested type would be the generic type definition.
4262 if (klass
->generic_class
)
4263 klass
= klass
->generic_class
->container_class
;
4267 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, len
);
4269 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4271 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4272 if (bflags
& BFLAGS_Public
)
4275 if (bflags
& BFLAGS_NonPublic
)
4280 member
= (MonoObject
*)mono_type_get_object (domain
, &nested
->byval_arg
);
4282 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.monotype_class
, len
* 2);
4283 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
4287 mono_array_setref (res
, i
, member
);
4291 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.monotype_class
, i
);
4292 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
4295 * Better solution for the new GC.
4296 * res->max_length = i;
4302 static MonoReflectionType
*
4303 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly
*assembly
, MonoReflectionModule
*module
, MonoString
*name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
)
4306 MonoType
*type
= NULL
;
4307 MonoTypeNameParse info
;
4308 gboolean type_resolve
;
4310 MONO_ARCH_SAVE_REGS
;
4312 /* On MS.NET, this does not fire a TypeResolve event */
4313 type_resolve
= TRUE
;
4314 str
= mono_string_to_utf8 (name
);
4315 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4316 if (!mono_reflection_parse_type (str
, &info
)) {
4318 mono_reflection_free_type_info (&info
);
4319 if (throwOnError
) /* uhm: this is a parse error, though... */
4320 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4321 /*g_print ("failed parse\n");*/
4325 if (info
.assembly
.name
) {
4327 mono_reflection_free_type_info (&info
);
4329 /* 1.0 and 2.0 throw different exceptions */
4330 if (mono_defaults
.generic_ilist_class
)
4331 mono_raise_exception (mono_get_exception_argument (NULL
, "Type names passed to Assembly.GetType() must not specify an assembly."));
4333 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4338 if (module
!= NULL
) {
4340 type
= mono_reflection_get_type (module
->image
, &info
, ignoreCase
, &type_resolve
);
4345 if (assembly
->assembly
->dynamic
) {
4346 /* Enumerate all modules */
4347 MonoReflectionAssemblyBuilder
*abuilder
= (MonoReflectionAssemblyBuilder
*)assembly
;
4351 if (abuilder
->modules
) {
4352 for (i
= 0; i
< mono_array_length (abuilder
->modules
); ++i
) {
4353 MonoReflectionModuleBuilder
*mb
= mono_array_get (abuilder
->modules
, MonoReflectionModuleBuilder
*, i
);
4354 type
= mono_reflection_get_type (&mb
->dynamic_image
->image
, &info
, ignoreCase
, &type_resolve
);
4360 if (!type
&& abuilder
->loaded_modules
) {
4361 for (i
= 0; i
< mono_array_length (abuilder
->loaded_modules
); ++i
) {
4362 MonoReflectionModule
*mod
= mono_array_get (abuilder
->loaded_modules
, MonoReflectionModule
*, i
);
4363 type
= mono_reflection_get_type (mod
->image
, &info
, ignoreCase
, &type_resolve
);
4370 type
= mono_reflection_get_type (assembly
->assembly
->image
, &info
, ignoreCase
, &type_resolve
);
4372 mono_reflection_free_type_info (&info
);
4374 MonoException
*e
= NULL
;
4377 e
= mono_get_exception_type_load (name
, NULL
);
4379 mono_loader_clear_error ();
4382 mono_raise_exception (e
);
4387 if (type
->type
== MONO_TYPE_CLASS
) {
4388 MonoClass
*klass
= mono_type_get_class (type
);
4390 if (mono_is_security_manager_active () && !klass
->exception_type
)
4391 /* Some security problems are detected during generic vtable construction */
4392 mono_class_setup_vtable (klass
);
4393 /* need to report exceptions ? */
4394 if (throwOnError
&& klass
->exception_type
) {
4395 /* report SecurityException (or others) that occured when loading the assembly */
4396 MonoException
*exc
= mono_class_get_exception_for_failure (klass
);
4397 mono_loader_clear_error ();
4398 mono_raise_exception (exc
);
4399 } else if (klass
->exception_type
== MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND
) {
4404 /* g_print ("got it\n"); */
4405 return mono_type_get_object (mono_object_domain (assembly
), type
);
4409 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly
*assembly
, MonoBoolean escaped
)
4411 MonoDomain
*domain
= mono_object_domain (assembly
);
4412 MonoAssembly
*mass
= assembly
->assembly
;
4413 MonoString
*res
= NULL
;
4417 gchar
*shadow_ini_file
;
4421 MONO_ARCH_SAVE_REGS
;
4423 if (g_path_is_absolute (mass
->image
->name
)) {
4424 absolute
= g_strdup (mass
->image
->name
);
4425 dirname
= g_path_get_dirname (absolute
);
4427 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4428 dirname
= g_strdup (mass
->basedir
);
4431 /* Check for shadow-copied assembly */
4432 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4433 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4435 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4436 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4442 g_free (shadow_ini_file
);
4443 if (content
!= NULL
) {
4453 for (i
= strlen (absolute
) - 1; i
>= 0; i
--)
4454 if (absolute
[i
] == '\\')
4459 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4461 const char *prepend
= "file://";
4463 if (*absolute
== '/' && *(absolute
+ 1) == '/') {
4466 prepend
= "file:///";
4469 uri
= g_strconcat (prepend
, absolute
, NULL
);
4473 res
= mono_string_new (domain
, uri
);
4481 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly
*assembly
)
4483 MonoAssembly
*mass
= assembly
->assembly
;
4485 MONO_ARCH_SAVE_REGS
;
4487 return mass
->in_gac
;
4490 static MonoReflectionAssembly
*
4491 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString
*mname
, MonoObject
*evidence
)
4495 MonoImageOpenStatus status
;
4497 MONO_ARCH_SAVE_REGS
;
4499 name
= mono_string_to_utf8 (mname
);
4500 res
= mono_assembly_load_with_partial_name (name
, &status
);
4506 return mono_assembly_get_object (mono_domain_get (), res
);
4510 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly
*assembly
)
4512 MonoDomain
*domain
= mono_object_domain (assembly
);
4515 MONO_ARCH_SAVE_REGS
;
4517 res
= mono_string_new (domain
, mono_image_get_filename (assembly
->assembly
->image
));
4523 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
*assembly
)
4525 MONO_ARCH_SAVE_REGS
;
4527 return assembly
->assembly
->ref_only
;
4531 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly
*assembly
)
4533 MonoDomain
*domain
= mono_object_domain (assembly
);
4535 MONO_ARCH_SAVE_REGS
;
4537 return mono_string_new (domain
, assembly
->assembly
->image
->version
);
4540 static MonoReflectionMethod
*
4541 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly
*assembly
)
4543 guint32 token
= mono_image_get_entry_point (assembly
->assembly
->image
);
4545 MONO_ARCH_SAVE_REGS
;
4549 return mono_method_get_object (mono_object_domain (assembly
), mono_get_method (assembly
->assembly
->image
, token
, NULL
), NULL
);
4552 static MonoReflectionModule
*
4553 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly
*assembly
)
4555 return mono_module_get_object (mono_object_domain (assembly
), assembly
->assembly
->image
);
4559 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly
*assembly
)
4561 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4562 MonoArray
*result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, table
->rows
);
4566 MONO_ARCH_SAVE_REGS
;
4568 for (i
= 0; i
< table
->rows
; ++i
) {
4569 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4570 mono_array_setref (result
, i
, mono_string_new (mono_object_domain (assembly
), val
));
4576 create_version (MonoDomain
*domain
, guint32 major
, guint32 minor
, guint32 build
, guint32 revision
)
4578 static MonoClass
*System_Version
= NULL
;
4579 static MonoMethod
*create_version
= NULL
;
4583 if (!System_Version
) {
4584 System_Version
= mono_class_from_name (mono_defaults
.corlib
, "System", "Version");
4585 g_assert (System_Version
);
4588 if (!create_version
) {
4589 MonoMethodDesc
*desc
= mono_method_desc_new (":.ctor(int,int,int,int)", FALSE
);
4590 create_version
= mono_method_desc_search_in_class (desc
, System_Version
);
4591 g_assert (create_version
);
4592 mono_method_desc_free (desc
);
4598 args
[3] = &revision
;
4599 result
= mono_object_new (domain
, System_Version
);
4600 mono_runtime_invoke (create_version
, result
, args
, NULL
);
4606 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly
*assembly
)
4608 static MonoClass
*System_Reflection_AssemblyName
;
4610 MonoDomain
*domain
= mono_object_domain (assembly
);
4612 static MonoMethod
*create_culture
= NULL
;
4613 MonoImage
*image
= assembly
->assembly
->image
;
4616 MONO_ARCH_SAVE_REGS
;
4618 if (!System_Reflection_AssemblyName
)
4619 System_Reflection_AssemblyName
= mono_class_from_name (
4620 mono_defaults
.corlib
, "System.Reflection", "AssemblyName");
4622 t
= &assembly
->assembly
->image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4625 result
= mono_array_new (domain
, System_Reflection_AssemblyName
, count
);
4628 MonoMethodDesc
*desc
= mono_method_desc_new (
4629 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4630 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4631 g_assert (create_culture
);
4632 mono_method_desc_free (desc
);
4635 for (i
= 0; i
< count
; i
++) {
4636 MonoReflectionAssemblyName
*aname
;
4637 guint32 cols
[MONO_ASSEMBLYREF_SIZE
];
4639 mono_metadata_decode_row (t
, i
, cols
, MONO_ASSEMBLYREF_SIZE
);
4641 aname
= (MonoReflectionAssemblyName
*) mono_object_new (
4642 domain
, System_Reflection_AssemblyName
);
4644 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_NAME
])));
4646 aname
->major
= cols
[MONO_ASSEMBLYREF_MAJOR_VERSION
];
4647 aname
->minor
= cols
[MONO_ASSEMBLYREF_MINOR_VERSION
];
4648 aname
->build
= cols
[MONO_ASSEMBLYREF_BUILD_NUMBER
];
4649 aname
->revision
= cols
[MONO_ASSEMBLYREF_REV_NUMBER
];
4650 aname
->flags
= cols
[MONO_ASSEMBLYREF_FLAGS
];
4651 aname
->versioncompat
= 1; /* SameMachine (default) */
4652 aname
->hashalg
= ASSEMBLY_HASH_SHA1
; /* SHA1 (default) */
4653 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, aname
->major
, aname
->minor
, aname
->build
, aname
->revision
));
4655 if (create_culture
) {
4657 MonoBoolean assembly_ref
= 1;
4658 args
[0] = mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_CULTURE
]));
4659 args
[1] = &assembly_ref
;
4660 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4663 if (cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]) {
4664 const gchar
*pkey_ptr
= mono_metadata_blob_heap (image
, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]);
4665 guint32 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4667 if ((cols
[MONO_ASSEMBLYREF_FLAGS
] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
)) {
4668 /* public key token isn't copied - the class library will
4669 automatically generate it from the public key if required */
4670 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4671 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4673 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4674 memcpy (mono_array_addr (aname
->keyToken
, guint8
, 0), pkey_ptr
, pkey_len
);
4677 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4680 /* note: this function doesn't return the codebase on purpose (i.e. it can
4681 be used under partial trust as path information isn't present). */
4683 mono_array_setref (result
, i
, aname
);
4694 foreach_namespace (const char* key
, gconstpointer val
, NameSpaceInfo
*info
)
4696 MonoString
*name
= mono_string_new (mono_object_domain (info
->res
), key
);
4698 mono_array_setref (info
->res
, info
->idx
, name
);
4703 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly
*assembly
)
4705 MonoImage
*img
= assembly
->assembly
->image
;
4709 MONO_ARCH_SAVE_REGS
;
4711 if (!img
->name_cache
)
4712 mono_image_init_name_cache (img
);
4714 res
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, g_hash_table_size (img
->name_cache
));
4717 g_hash_table_foreach (img
->name_cache
, (GHFunc
)foreach_namespace
, &info
);
4722 /* move this in some file in mono/util/ */
4724 g_concat_dir_and_file (const char *dir
, const char *file
)
4726 g_return_val_if_fail (dir
!= NULL
, NULL
);
4727 g_return_val_if_fail (file
!= NULL
, NULL
);
4730 * If the directory name doesn't have a / on the end, we need
4731 * to add one so we get a proper path to the file
4733 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4734 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4736 return g_strconcat (dir
, file
, NULL
);
4740 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, gint32
*size
, MonoReflectionModule
**ref_module
)
4742 char *n
= mono_string_to_utf8 (name
);
4743 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4745 guint32 cols
[MONO_MANIFEST_SIZE
];
4746 guint32 impl
, file_idx
;
4750 MONO_ARCH_SAVE_REGS
;
4752 for (i
= 0; i
< table
->rows
; ++i
) {
4753 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4754 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4755 if (strcmp (val
, n
) == 0)
4759 if (i
== table
->rows
)
4762 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4765 * this code should only be called after obtaining the
4766 * ResourceInfo and handling the other cases.
4768 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4769 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4771 module
= mono_image_load_file_for_image (assembly
->assembly
->image
, file_idx
);
4776 module
= assembly
->assembly
->image
;
4778 *ref_module
= mono_module_get_object (mono_domain_get (), module
);
4780 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4784 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoManifestResourceInfo
*info
)
4786 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4788 guint32 cols
[MONO_MANIFEST_SIZE
];
4789 guint32 file_cols
[MONO_FILE_SIZE
];
4793 MONO_ARCH_SAVE_REGS
;
4795 n
= mono_string_to_utf8 (name
);
4796 for (i
= 0; i
< table
->rows
; ++i
) {
4797 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4798 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4799 if (strcmp (val
, n
) == 0)
4803 if (i
== table
->rows
)
4806 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4807 info
->location
= RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
;
4810 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4811 case MONO_IMPLEMENTATION_FILE
:
4812 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4813 table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4814 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4815 val
= mono_metadata_string_heap (assembly
->assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4816 MONO_OBJECT_SETREF (info
, filename
, mono_string_new (mono_object_domain (assembly
), val
));
4817 if (file_cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4820 info
->location
= RESOURCE_LOCATION_EMBEDDED
;
4823 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4824 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4825 mono_assembly_load_reference (assembly
->assembly
->image
, i
- 1);
4826 if (assembly
->assembly
->image
->references
[i
- 1] == (gpointer
)-1) {
4827 char *msg
= g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->assembly
->image
->name
);
4828 MonoException
*ex
= mono_get_exception_file_not_found2 (msg
, NULL
);
4830 mono_raise_exception (ex
);
4832 MONO_OBJECT_SETREF (info
, assembly
, mono_assembly_get_object (mono_domain_get (), assembly
->assembly
->image
->references
[i
- 1]));
4834 /* Obtain info recursively */
4835 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info
->assembly
, name
, info
);
4836 info
->location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4839 case MONO_IMPLEMENTATION_EXP_TYPE
:
4840 g_assert_not_reached ();
4849 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoBoolean resource_modules
)
4851 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4852 MonoArray
*result
= NULL
;
4857 MONO_ARCH_SAVE_REGS
;
4859 /* check hash if needed */
4861 n
= mono_string_to_utf8 (name
);
4862 for (i
= 0; i
< table
->rows
; ++i
) {
4863 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4864 if (strcmp (val
, n
) == 0) {
4867 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4868 fn
= mono_string_new (mono_object_domain (assembly
), n
);
4870 return (MonoObject
*)fn
;
4878 for (i
= 0; i
< table
->rows
; ++i
) {
4879 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
4883 result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, count
);
4886 for (i
= 0; i
< table
->rows
; ++i
) {
4887 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
4888 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4889 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4890 mono_array_setref (result
, count
, mono_string_new (mono_object_domain (assembly
), n
));
4895 return (MonoObject
*)result
;
4899 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
*assembly
)
4901 MonoDomain
*domain
= mono_domain_get();
4904 int i
, j
, file_count
= 0;
4905 MonoImage
**modules
;
4906 guint32 module_count
, real_module_count
;
4907 MonoTableInfo
*table
;
4908 guint32 cols
[MONO_FILE_SIZE
];
4909 MonoImage
*image
= assembly
->assembly
->image
;
4911 g_assert (image
!= NULL
);
4912 g_assert (!assembly
->assembly
->dynamic
);
4914 table
= &image
->tables
[MONO_TABLE_FILE
];
4915 file_count
= table
->rows
;
4917 modules
= image
->modules
;
4918 module_count
= image
->module_count
;
4920 real_module_count
= 0;
4921 for (i
= 0; i
< module_count
; ++i
)
4923 real_module_count
++;
4925 klass
= mono_class_from_name (mono_defaults
.corlib
, "System.Reflection", "Module");
4926 res
= mono_array_new (domain
, klass
, 1 + real_module_count
+ file_count
);
4928 mono_array_setref (res
, 0, mono_module_get_object (domain
, image
));
4930 for (i
= 0; i
< module_count
; ++i
)
4932 mono_array_setref (res
, j
, mono_module_get_object (domain
, modules
[i
]));
4936 for (i
= 0; i
< file_count
; ++i
, ++j
) {
4937 mono_metadata_decode_row (table
, i
, cols
, MONO_FILE_SIZE
);
4938 if (cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4939 mono_array_setref (res
, j
, mono_module_file_get_object (domain
, image
, i
));
4941 MonoImage
*m
= mono_image_load_file_for_image (image
, i
+ 1);
4943 MonoString
*fname
= mono_string_new (mono_domain_get (), mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]));
4944 mono_raise_exception (mono_get_exception_file_not_found2 (NULL
, fname
));
4946 mono_array_setref (res
, j
, mono_module_get_object (domain
, m
));
4953 static MonoReflectionMethod
*
4954 ves_icall_GetCurrentMethod (void)
4956 MonoMethod
*m
= mono_method_get_last_managed ();
4958 MONO_ARCH_SAVE_REGS
;
4960 return mono_method_get_object (mono_domain_get (), m
, NULL
);
4965 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
4968 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
4969 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
4970 //method is inflated, we should inflate it on the other class
4971 MonoGenericContext ctx
;
4972 ctx
.method_inst
= inflated
->context
.method_inst
;
4973 ctx
.class_inst
= inflated
->context
.class_inst
;
4974 if (klass
->generic_class
)
4975 ctx
.class_inst
= klass
->generic_class
->context
.class_inst
;
4976 else if (klass
->generic_container
)
4977 ctx
.class_inst
= klass
->generic_container
->context
.class_inst
;
4978 return mono_class_inflate_generic_method_full (inflated
->declaring
, klass
, &ctx
);
4981 mono_class_setup_methods (method
->klass
);
4982 for (i
= 0; i
< method
->klass
->method
.count
; ++i
) {
4983 if (method
->klass
->methods
[i
] == method
) {
4988 mono_class_setup_methods (klass
);
4989 g_assert (offset
>= 0 && offset
< klass
->method
.count
);
4990 return klass
->methods
[offset
];
4993 static MonoReflectionMethod
*
4994 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod
*method
, MonoType
*type
)
4998 klass
= mono_class_from_mono_type (type
);
4999 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
5001 if (method
->klass
!= klass
)
5002 method
= mono_method_get_equivalent_method (method
, klass
);
5004 klass
= method
->klass
;
5005 return mono_method_get_object (mono_domain_get (), method
, klass
);
5008 static MonoReflectionMethod
*
5009 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod
*method
)
5011 return mono_method_get_object (mono_domain_get (), method
, NULL
);
5014 static MonoReflectionMethodBody
*
5015 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
)
5017 return mono_method_body_get_object (mono_domain_get (), method
);
5020 static MonoReflectionAssembly
*
5021 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5023 MonoMethod
*dest
= NULL
;
5025 MONO_ARCH_SAVE_REGS
;
5027 mono_stack_walk_no_il (get_executing
, &dest
);
5028 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
5032 static MonoReflectionAssembly
*
5033 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5035 MonoDomain
* domain
= mono_domain_get ();
5037 MONO_ARCH_SAVE_REGS
;
5039 if (!domain
->entry_assembly
)
5042 return mono_assembly_get_object (domain
, domain
->entry_assembly
);
5045 static MonoReflectionAssembly
*
5046 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5051 MONO_ARCH_SAVE_REGS
;
5054 mono_stack_walk_no_il (get_executing
, &dest
);
5056 mono_stack_walk_no_il (get_caller
, &dest
);
5059 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
5063 ves_icall_System_MonoType_getFullName (MonoReflectionType
*object
, gboolean full_name
,
5064 gboolean assembly_qualified
)
5066 MonoDomain
*domain
= mono_object_domain (object
);
5067 MonoTypeNameFormat format
;
5071 MONO_ARCH_SAVE_REGS
;
5073 format
= assembly_qualified
?
5074 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
5075 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
5077 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
5079 name
= mono_type_get_name_full (object
->type
, format
);
5083 if (full_name
&& (object
->type
->type
== MONO_TYPE_VAR
|| object
->type
->type
== MONO_TYPE_MVAR
)) {
5088 res
= mono_string_new (domain
, name
);
5095 fill_reflection_assembly_name (MonoDomain
*domain
, MonoReflectionAssemblyName
*aname
, MonoAssemblyName
*name
, const char *absolute
, gboolean by_default_version
, gboolean default_publickey
, gboolean default_token
)
5097 static MonoMethod
*create_culture
= NULL
;
5100 const char *pkey_ptr
;
5102 MonoBoolean assembly_ref
= 0;
5104 MONO_ARCH_SAVE_REGS
;
5106 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, name
->name
));
5107 aname
->major
= name
->major
;
5108 aname
->minor
= name
->minor
;
5109 aname
->build
= name
->build
;
5110 aname
->flags
= name
->flags
;
5111 aname
->revision
= name
->revision
;
5112 aname
->hashalg
= name
->hash_alg
;
5113 aname
->versioncompat
= 1; /* SameMachine (default) */
5115 if (by_default_version
)
5116 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, name
->major
, name
->minor
, name
->build
, name
->revision
));
5119 if (absolute
!= NULL
&& *absolute
!= '\0') {
5120 const gchar
*prepend
= "file://";
5123 codebase
= g_strdup (absolute
);
5128 for (i
= strlen (codebase
) - 1; i
>= 0; i
--)
5129 if (codebase
[i
] == '\\')
5132 if (*codebase
== '/' && *(codebase
+ 1) == '/') {
5135 prepend
= "file:///";
5139 result
= g_strconcat (prepend
, codebase
, NULL
);
5145 MONO_OBJECT_SETREF (aname
, codebase
, mono_string_new (domain
, codebase
));
5149 if (!create_culture
) {
5150 MonoMethodDesc
*desc
= mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
5151 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
5152 g_assert (create_culture
);
5153 mono_method_desc_free (desc
);
5156 if (name
->culture
) {
5157 args
[0] = mono_string_new (domain
, name
->culture
);
5158 args
[1] = &assembly_ref
;
5159 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
5162 if (name
->public_key
) {
5163 pkey_ptr
= (char*)name
->public_key
;
5164 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
5166 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
5167 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
5168 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
5169 } else if (default_publickey
) {
5170 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
5171 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
5174 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5175 if (name
->public_key_token
[0]) {
5179 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 8));
5180 p
= mono_array_addr (aname
->keyToken
, char, 0);
5182 for (i
= 0, j
= 0; i
< 8; i
++) {
5183 *p
= g_ascii_xdigit_value (name
->public_key_token
[j
++]) << 4;
5184 *p
|= g_ascii_xdigit_value (name
->public_key_token
[j
++]);
5187 } else if (default_token
) {
5188 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
5193 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly
*assembly
)
5195 MonoDomain
*domain
= mono_object_domain (assembly
);
5196 MonoAssembly
*mass
= assembly
->assembly
;
5200 name
= g_strdup_printf (
5201 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
5203 mass
->aname
.major
, mass
->aname
.minor
, mass
->aname
.build
, mass
->aname
.revision
,
5204 mass
->aname
.culture
&& *mass
->aname
.culture
? mass
->aname
.culture
: "neutral",
5205 mass
->aname
.public_key_token
[0] ? (char *)mass
->aname
.public_key_token
: "null",
5206 (mass
->aname
.flags
& ASSEMBLYREF_RETARGETABLE_FLAG
) ? ", Retargetable=Yes" : "");
5208 res
= mono_string_new (domain
, name
);
5215 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly
*assembly
, MonoReflectionAssemblyName
*aname
)
5218 MonoAssembly
*mass
= assembly
->assembly
;
5220 MONO_ARCH_SAVE_REGS
;
5222 if (g_path_is_absolute (mass
->image
->name
)) {
5223 fill_reflection_assembly_name (mono_object_domain (assembly
),
5224 aname
, &mass
->aname
, mass
->image
->name
, TRUE
,
5225 TRUE
, mono_framework_version () >= 2);
5228 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
5230 fill_reflection_assembly_name (mono_object_domain (assembly
),
5231 aname
, &mass
->aname
, absolute
, TRUE
, TRUE
,
5232 mono_framework_version () >= 2);
5238 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString
*fname
, MonoReflectionAssemblyName
*aname
)
5241 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
5244 MonoAssemblyName name
;
5246 MONO_ARCH_SAVE_REGS
;
5248 filename
= mono_string_to_utf8 (fname
);
5250 image
= mono_image_open (filename
, &status
);
5256 if (status
== MONO_IMAGE_IMAGE_INVALID
)
5257 exc
= mono_get_exception_bad_image_format2 (NULL
, fname
);
5259 exc
= mono_get_exception_file_not_found2 (NULL
, fname
);
5260 mono_raise_exception (exc
);
5263 res
= mono_assembly_fill_assembly_name (image
, &name
);
5265 mono_image_close (image
);
5267 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5270 fill_reflection_assembly_name (mono_domain_get (), aname
, &name
, filename
,
5271 TRUE
, mono_framework_version () == 1,
5272 mono_framework_version () >= 2);
5275 mono_image_close (image
);
5279 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly
*assembly
,
5280 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
)
5282 MonoBoolean result
= FALSE
;
5283 MonoDeclSecurityEntry entry
;
5285 /* SecurityAction.RequestMinimum */
5286 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5287 *minimum
= entry
.blob
;
5288 *minLength
= entry
.size
;
5291 /* SecurityAction.RequestOptional */
5292 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5293 *optional
= entry
.blob
;
5294 *optLength
= entry
.size
;
5297 /* SecurityAction.RequestRefuse */
5298 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5299 *refused
= entry
.blob
;
5300 *refLength
= entry
.size
;
5308 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArray
**exceptions
, MonoBoolean exportedOnly
)
5312 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5314 guint32 attrs
, visibility
;
5316 /* we start the count from 1 because we skip the special type <Module> */
5319 for (i
= 1; i
< tdef
->rows
; ++i
) {
5320 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5321 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5322 if (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5326 count
= tdef
->rows
- 1;
5328 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
5329 *exceptions
= mono_array_new (domain
, mono_defaults
.exception_class
, count
);
5331 for (i
= 1; i
< tdef
->rows
; ++i
) {
5332 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5333 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5334 if (!exportedOnly
|| (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)) {
5335 klass
= mono_class_get (image
, (i
+ 1) | MONO_TOKEN_TYPE_DEF
);
5337 mono_array_setref (res
, count
, mono_type_get_object (domain
, &klass
->byval_arg
));
5339 MonoLoaderError
*error
;
5342 error
= mono_loader_get_last_error ();
5343 g_assert (error
!= NULL
);
5345 ex
= mono_loader_error_prepare_exception (error
);
5346 mono_array_setref (*exceptions
, count
, ex
);
5348 if (mono_loader_get_last_error ())
5349 mono_loader_clear_error ();
5358 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly
*assembly
, MonoBoolean exportedOnly
)
5360 MonoArray
*res
= NULL
;
5361 MonoArray
*exceptions
= NULL
;
5362 MonoImage
*image
= NULL
;
5363 MonoTableInfo
*table
= NULL
;
5366 int i
, len
, ex_count
;
5368 MONO_ARCH_SAVE_REGS
;
5370 domain
= mono_object_domain (assembly
);
5372 g_assert (!assembly
->assembly
->dynamic
);
5373 image
= assembly
->assembly
->image
;
5374 table
= &image
->tables
[MONO_TABLE_FILE
];
5375 res
= mono_module_get_types (domain
, image
, &exceptions
, exportedOnly
);
5377 /* Append data from all modules in the assembly */
5378 for (i
= 0; i
< table
->rows
; ++i
) {
5379 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5380 MonoImage
*loaded_image
= mono_assembly_load_module (image
->assembly
, i
+ 1);
5383 MonoArray
*res2
= mono_module_get_types (domain
, loaded_image
, &ex2
, exportedOnly
);
5384 /* Append the new types to the end of the array */
5385 if (mono_array_length (res2
) > 0) {
5387 MonoArray
*res3
, *ex3
;
5389 len1
= mono_array_length (res
);
5390 len2
= mono_array_length (res2
);
5392 res3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5393 mono_array_memcpy_refs (res3
, 0, res
, 0, len1
);
5394 mono_array_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5397 ex3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5398 mono_array_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5399 mono_array_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5406 /* the ReflectionTypeLoadException must have all the types (Types property),
5407 * NULL replacing types which throws an exception. The LoaderException must
5408 * contain all exceptions for NULL items.
5411 len
= mono_array_length (res
);
5414 for (i
= 0; i
< len
; i
++) {
5415 MonoReflectionType
*t
= mono_array_get (res
, gpointer
, i
);
5419 klass
= mono_type_get_class (t
->type
);
5420 if ((klass
!= NULL
) && klass
->exception_type
) {
5421 /* keep the class in the list */
5422 list
= g_list_append (list
, klass
);
5423 /* and replace Type with NULL */
5424 mono_array_setref (res
, i
, NULL
);
5431 if (list
|| ex_count
) {
5433 MonoException
*exc
= NULL
;
5434 MonoArray
*exl
= NULL
;
5435 int j
, length
= g_list_length (list
) + ex_count
;
5437 mono_loader_clear_error ();
5439 exl
= mono_array_new (domain
, mono_defaults
.exception_class
, length
);
5440 /* Types for which mono_class_get () succeeded */
5441 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5442 MonoException
*exc
= mono_class_get_exception_for_failure (tmp
->data
);
5443 mono_array_setref (exl
, i
, exc
);
5445 /* Types for which it don't */
5446 for (j
= 0; j
< mono_array_length (exceptions
); ++j
) {
5447 MonoException
*exc
= mono_array_get (exceptions
, MonoException
*, j
);
5449 g_assert (i
< length
);
5450 mono_array_setref (exl
, i
, exc
);
5457 exc
= mono_get_exception_reflection_type_load (res
, exl
);
5458 mono_loader_clear_error ();
5459 mono_raise_exception (exc
);
5466 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName
*name
, MonoString
*assname
)
5468 MonoAssemblyName aname
;
5469 MonoDomain
*domain
= mono_object_domain (name
);
5471 gboolean is_version_defined
;
5472 gboolean is_token_defined
;
5474 aname
.public_key
= NULL
;
5475 val
= mono_string_to_utf8 (assname
);
5476 if (!mono_assembly_name_parse_full (val
, &aname
, TRUE
, &is_version_defined
, &is_token_defined
)) {
5477 g_free ((guint8
*) aname
.public_key
);
5482 fill_reflection_assembly_name (domain
, name
, &aname
, "", is_version_defined
,
5483 FALSE
, is_token_defined
);
5485 mono_assembly_name_free (&aname
);
5486 g_free ((guint8
*) aname
.public_key
);
5492 static MonoReflectionType
*
5493 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule
*module
)
5495 MonoDomain
*domain
= mono_object_domain (module
);
5498 MONO_ARCH_SAVE_REGS
;
5500 g_assert (module
->image
);
5502 if (module
->image
->dynamic
&& ((MonoDynamicImage
*)(module
->image
))->initial_image
)
5503 /* These images do not have a global type */
5506 klass
= mono_class_get (module
->image
, 1 | MONO_TOKEN_TYPE_DEF
);
5507 return mono_type_get_object (domain
, &klass
->byval_arg
);
5511 ves_icall_System_Reflection_Module_Close (MonoReflectionModule
*module
)
5513 /*if (module->image)
5514 mono_image_close (module->image);*/
5518 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule
*module
)
5520 MonoDomain
*domain
= mono_object_domain (module
);
5522 MONO_ARCH_SAVE_REGS
;
5524 g_assert (module
->image
);
5525 return mono_string_new (domain
, module
->image
->guid
);
5529 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule
*module
)
5531 #ifdef PLATFORM_WIN32
5532 if (module
->image
&& module
->image
->is_module_handle
)
5533 return module
->image
->raw_data
;
5536 return (gpointer
) (-1);
5540 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
)
5542 if (image
->dynamic
) {
5543 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5544 *pe_kind
= dyn
->pe_kind
;
5545 *machine
= dyn
->machine
;
5548 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5549 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5554 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
)
5556 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5560 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule
*module
)
5562 MonoArray
*exceptions
;
5565 MONO_ARCH_SAVE_REGS
;
5568 return mono_array_new (mono_object_domain (module
), mono_defaults
.monotype_class
, 0);
5570 MonoArray
*res
= mono_module_get_types (mono_object_domain (module
), module
->image
, &exceptions
, FALSE
);
5571 for (i
= 0; i
< mono_array_length (exceptions
); ++i
) {
5572 MonoException
*ex
= mono_array_get (exceptions
, MonoException
*, i
);
5574 mono_raise_exception (ex
);
5581 mono_metadata_memberref_is_method (MonoImage
*image
, guint32 token
)
5583 guint32 cols
[MONO_MEMBERREF_SIZE
];
5585 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5586 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5587 mono_metadata_decode_blob_size (sig
, &sig
);
5588 return (*sig
!= 0x6);
5592 init_generic_context_from_args (MonoGenericContext
*context
, MonoArray
*type_args
, MonoArray
*method_args
)
5595 context
->class_inst
= mono_metadata_get_generic_inst (mono_array_length (type_args
),
5596 mono_array_addr (type_args
, MonoType
*, 0));
5598 context
->class_inst
= NULL
;
5600 context
->method_inst
= mono_metadata_get_generic_inst (mono_array_length (method_args
),
5601 mono_array_addr (method_args
, MonoType
*, 0));
5603 context
->method_inst
= NULL
;
5607 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5610 int table
= mono_metadata_token_table (token
);
5611 int index
= mono_metadata_token_index (token
);
5612 MonoGenericContext context
;
5614 *error
= ResolveTokenError_Other
;
5616 /* Validate token */
5617 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5618 (table
!= MONO_TABLE_TYPESPEC
)) {
5619 *error
= ResolveTokenError_BadTable
;
5623 if (image
->dynamic
) {
5624 if (type_args
|| method_args
)
5625 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5626 klass
= mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5629 return &klass
->byval_arg
;
5632 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5633 *error
= ResolveTokenError_OutOfRange
;
5637 init_generic_context_from_args (&context
, type_args
, method_args
);
5638 klass
= mono_class_get_full (image
, token
, &context
);
5640 if (mono_loader_get_last_error ())
5641 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5644 return &klass
->byval_arg
;
5650 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5652 int table
= mono_metadata_token_table (token
);
5653 int index
= mono_metadata_token_index (token
);
5654 MonoGenericContext context
;
5657 *error
= ResolveTokenError_Other
;
5659 /* Validate token */
5660 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5661 (table
!= MONO_TABLE_MEMBERREF
)) {
5662 *error
= ResolveTokenError_BadTable
;
5666 if (image
->dynamic
) {
5667 if (type_args
|| method_args
)
5668 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5669 /* FIXME: validate memberref token type */
5670 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5673 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5674 *error
= ResolveTokenError_OutOfRange
;
5677 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_metadata_memberref_is_method (image
, token
))) {
5678 *error
= ResolveTokenError_BadTable
;
5682 init_generic_context_from_args (&context
, type_args
, method_args
);
5683 method
= mono_get_method_full (image
, token
, NULL
, &context
);
5685 if (mono_loader_get_last_error ())
5686 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5692 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5694 int index
= mono_metadata_token_index (token
);
5696 *error
= ResolveTokenError_Other
;
5698 /* Validate token */
5699 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5700 *error
= ResolveTokenError_BadTable
;
5705 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5707 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5708 *error
= ResolveTokenError_OutOfRange
;
5712 /* FIXME: What to do if the index points into the middle of a string ? */
5714 return mono_ldstr (mono_domain_get (), image
, index
);
5717 static MonoClassField
*
5718 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5721 int table
= mono_metadata_token_table (token
);
5722 int index
= mono_metadata_token_index (token
);
5723 MonoGenericContext context
;
5724 MonoClassField
*field
;
5726 *error
= ResolveTokenError_Other
;
5728 /* Validate token */
5729 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
5730 *error
= ResolveTokenError_BadTable
;
5734 if (image
->dynamic
) {
5735 if (type_args
|| method_args
)
5736 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5737 /* FIXME: validate memberref token type */
5738 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5741 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5742 *error
= ResolveTokenError_OutOfRange
;
5745 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_metadata_memberref_is_method (image
, token
))) {
5746 *error
= ResolveTokenError_BadTable
;
5750 init_generic_context_from_args (&context
, type_args
, method_args
);
5751 field
= mono_field_from_token (image
, token
, &klass
, &context
);
5753 if (mono_loader_get_last_error ())
5754 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5761 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5763 int table
= mono_metadata_token_table (token
);
5765 *error
= ResolveTokenError_Other
;
5768 case MONO_TABLE_TYPEDEF
:
5769 case MONO_TABLE_TYPEREF
:
5770 case MONO_TABLE_TYPESPEC
: {
5771 MonoType
*t
= ves_icall_System_Reflection_Module_ResolveTypeToken (image
, token
, type_args
, method_args
, error
);
5773 return (MonoObject
*)mono_type_get_object (mono_domain_get (), t
);
5777 case MONO_TABLE_METHOD
:
5778 case MONO_TABLE_METHODSPEC
: {
5779 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5781 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5785 case MONO_TABLE_FIELD
: {
5786 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5788 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5792 case MONO_TABLE_MEMBERREF
:
5793 if (mono_metadata_memberref_is_method (image
, token
)) {
5794 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5796 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5801 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5803 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5810 *error
= ResolveTokenError_BadTable
;
5817 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5819 int table
= mono_metadata_token_table (token
);
5820 int idx
= mono_metadata_token_index (token
);
5821 MonoTableInfo
*tables
= image
->tables
;
5826 *error
= ResolveTokenError_OutOfRange
;
5828 /* FIXME: Support other tables ? */
5829 if (table
!= MONO_TABLE_STANDALONESIG
)
5835 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
5838 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
5840 ptr
= mono_metadata_blob_heap (image
, sig
);
5841 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
5843 res
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, len
);
5844 memcpy (mono_array_addr (res
, guint8
, 0), ptr
, len
);
5848 static MonoReflectionType
*
5849 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder
*tb
, MonoString
*smodifiers
)
5852 int isbyref
= 0, rank
;
5853 char *str
= mono_string_to_utf8 (smodifiers
);
5856 MONO_ARCH_SAVE_REGS
;
5858 klass
= mono_class_from_mono_type (tb
->type
.type
);
5860 /* logic taken from mono_reflection_parse_type(): keep in sync */
5864 if (isbyref
) { /* only one level allowed by the spec */
5871 return mono_type_get_object (mono_object_domain (tb
), &klass
->this_arg
);
5874 klass
= mono_ptr_class_get (&klass
->byval_arg
);
5875 mono_class_init (klass
);
5886 else if (*p
!= '*') { /* '*' means unknown lower bound */
5897 klass
= mono_array_class_get (klass
, rank
);
5898 mono_class_init (klass
);
5905 return mono_type_get_object (mono_object_domain (tb
), &klass
->byval_arg
);
5909 ves_icall_Type_IsArrayImpl (MonoReflectionType
*t
)
5914 MONO_ARCH_SAVE_REGS
;
5917 res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
5922 static MonoReflectionType
*
5923 ves_icall_Type_make_array_type (MonoReflectionType
*type
, int rank
)
5925 MonoClass
*klass
, *aklass
;
5927 MONO_ARCH_SAVE_REGS
;
5929 klass
= mono_class_from_mono_type (type
->type
);
5930 aklass
= mono_array_class_get (klass
, rank
);
5932 return mono_type_get_object (mono_object_domain (type
), &aklass
->byval_arg
);
5935 static MonoReflectionType
*
5936 ves_icall_Type_make_byref_type (MonoReflectionType
*type
)
5940 MONO_ARCH_SAVE_REGS
;
5942 klass
= mono_class_from_mono_type (type
->type
);
5944 return mono_type_get_object (mono_object_domain (type
), &klass
->this_arg
);
5947 static MonoReflectionType
*
5948 ves_icall_Type_MakePointerType (MonoReflectionType
*type
)
5952 MONO_ARCH_SAVE_REGS
;
5954 pklass
= mono_ptr_class_get (type
->type
);
5956 return mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
);
5960 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType
*type
, MonoObject
*target
,
5961 MonoReflectionMethod
*info
)
5963 MonoClass
*delegate_class
= mono_class_from_mono_type (type
->type
);
5964 MonoObject
*delegate
;
5966 MonoMethod
*method
= info
->method
;
5968 MONO_ARCH_SAVE_REGS
;
5970 mono_assert (delegate_class
->parent
== mono_defaults
.multicastdelegate_class
);
5972 /* FIME: We must check if target is visible to the caller under coreclr.
5973 * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
5976 delegate
= mono_object_new (mono_object_domain (type
), delegate_class
);
5978 if (mono_method_needs_static_rgctx_invoke (method
, FALSE
)) {
5979 method
= mono_marshal_get_static_rgctx_invoke (method
);
5980 func
= mono_compile_method (method
);
5981 } else if (method
->dynamic
) {
5982 /* Creating a trampoline would leak memory */
5983 func
= mono_compile_method (method
);
5985 func
= mono_create_ftnptr (mono_domain_get (),
5986 mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
));
5989 mono_delegate_ctor_with_method (delegate
, target
, func
, method
);
5995 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate
*this)
5997 /* Reset the invoke impl to the default one */
5998 this->invoke_impl
= mono_runtime_create_delegate_trampoline (this->object
.vtable
->klass
);
6002 * Magic number to convert a time which is relative to
6003 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
6005 #define EPOCH_ADJUST ((guint64)62135596800LL)
6008 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
6010 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
6012 #ifdef PLATFORM_WIN32
6013 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
6015 convert_to_absolute_date(SYSTEMTIME
*date
)
6017 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
6018 static int days_in_month
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
6019 static int leap_days_in_month
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
6020 /* from the calendar FAQ */
6021 int a
= (14 - date
->wMonth
) / 12;
6022 int y
= date
->wYear
- a
;
6023 int m
= date
->wMonth
+ 12 * a
- 2;
6024 int d
= (1 + y
+ y
/4 - y
/100 + y
/400 + (31*m
)/12) % 7;
6026 /* d is now the day of the week for the first of the month (0 == Sunday) */
6028 int day_of_week
= date
->wDayOfWeek
;
6030 /* set day_in_month to the first day in the month which falls on day_of_week */
6031 int day_in_month
= 1 + (day_of_week
- d
);
6032 if (day_in_month
<= 0)
6035 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
6036 date
->wDay
= day_in_month
+ (date
->wDay
- 1) * 7;
6037 if (date
->wDay
> (IS_LEAP(date
->wYear
) ? leap_days_in_month
[date
->wMonth
- 1] : days_in_month
[date
->wMonth
- 1]))
6042 #ifndef PLATFORM_WIN32
6044 * Return's the offset from GMT of a local time.
6046 * tm is a local time
6047 * t is the same local time as seconds.
6050 gmt_offset(struct tm
*tm
, time_t t
)
6052 #if defined (HAVE_TM_GMTOFF)
6053 return tm
->tm_gmtoff
;
6058 g
.tm_isdst
= tm
->tm_isdst
;
6060 return (int)difftime(t
, t2
);
6065 * This is heavily based on zdump.c from glibc 2.2.
6067 * * data[0]: start of daylight saving time (in DateTime ticks).
6068 * * data[1]: end of daylight saving time (in DateTime ticks).
6069 * * data[2]: utcoffset (in TimeSpan ticks).
6070 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
6071 * * name[0]: name of this timezone when not daylight saving.
6072 * * name[1]: name of this timezone when daylight saving.
6074 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
6075 * the class library allows years between 1 and 9999.
6077 * Returns true on success and zero on failure.
6080 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year
, MonoArray
**data
, MonoArray
**names
)
6082 #ifndef PLATFORM_WIN32
6083 MonoDomain
*domain
= mono_domain_get ();
6084 struct tm start
, tt
;
6088 int is_daylight
= 0, day
;
6091 MONO_ARCH_SAVE_REGS
;
6093 MONO_CHECK_ARG_NULL (data
);
6094 MONO_CHECK_ARG_NULL (names
);
6096 (*data
) = mono_array_new (domain
, mono_defaults
.int64_class
, 4);
6097 (*names
) = mono_array_new (domain
, mono_defaults
.string_class
, 2);
6100 * no info is better than crashing: we'll need our own tz data
6101 * to make this work properly, anyway. The range is probably
6102 * reduced to 1970 .. 2037 because that is what mktime is
6103 * guaranteed to support (we get into an infinite loop
6107 memset (&start
, 0, sizeof (start
));
6110 start
.tm_year
= year
-1900;
6112 t
= mktime (&start
);
6114 if ((year
< 1970) || (year
> 2037) || (t
== -1)) {
6116 tt
= *localtime (&t
);
6117 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6118 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6119 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6123 gmtoff
= gmt_offset (&start
, t
);
6125 /* For each day of the year, calculate the tm_gmtoff. */
6126 for (day
= 0; day
< 365; day
++) {
6129 tt
= *localtime (&t
);
6131 /* Daylight saving starts or ends here. */
6132 if (gmt_offset (&tt
, t
) != gmtoff
) {
6136 /* Try to find the exact hour when daylight saving starts/ends. */
6140 tt1
= *localtime (&t1
);
6141 } while (gmt_offset (&tt1
, t1
) != gmtoff
);
6143 /* Try to find the exact minute when daylight saving starts/ends. */
6146 tt1
= *localtime (&t1
);
6147 } while (gmt_offset (&tt1
, t1
) == gmtoff
);
6149 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6151 /* Write data, if we're already in daylight saving, we're done. */
6153 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6154 mono_array_set ((*data
), gint64
, 1, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
6157 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6158 mono_array_set ((*data
), gint64
, 0, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
6162 /* This is only set once when we enter daylight saving. */
6163 mono_array_set ((*data
), gint64
, 2, (gint64
)gmtoff
* 10000000L);
6164 mono_array_set ((*data
), gint64
, 3, (gint64
)(gmt_offset (&tt
, t
) - gmtoff
) * 10000000L);
6166 gmtoff
= gmt_offset (&tt
, t
);
6171 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6172 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6173 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6174 mono_array_set ((*data
), gint64
, 0, 0);
6175 mono_array_set ((*data
), gint64
, 1, 0);
6176 mono_array_set ((*data
), gint64
, 2, (gint64
) gmtoff
* 10000000L);
6177 mono_array_set ((*data
), gint64
, 3, 0);
6182 MonoDomain
*domain
= mono_domain_get ();
6183 TIME_ZONE_INFORMATION tz_info
;
6188 tz_id
= GetTimeZoneInformation (&tz_info
);
6189 if (tz_id
== TIME_ZONE_ID_INVALID
)
6192 MONO_CHECK_ARG_NULL (data
);
6193 MONO_CHECK_ARG_NULL (names
);
6195 (*data
) = mono_array_new (domain
, mono_defaults
.int64_class
, 4);
6196 (*names
) = mono_array_new (domain
, mono_defaults
.string_class
, 2);
6198 for (i
= 0; i
< 32; ++i
)
6199 if (!tz_info
.DaylightName
[i
])
6201 mono_array_setref ((*names
), 1, mono_string_new_utf16 (domain
, tz_info
.DaylightName
, i
));
6202 for (i
= 0; i
< 32; ++i
)
6203 if (!tz_info
.StandardName
[i
])
6205 mono_array_setref ((*names
), 0, mono_string_new_utf16 (domain
, tz_info
.StandardName
, i
));
6207 if ((year
<= 1601) || (year
> 30827)) {
6209 * According to MSDN, the MS time functions can't handle dates outside
6215 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
6216 if (tz_id
!= TIME_ZONE_ID_UNKNOWN
) {
6217 tz_info
.StandardDate
.wYear
= year
;
6218 convert_to_absolute_date(&tz_info
.StandardDate
);
6219 err
= SystemTimeToFileTime (&tz_info
.StandardDate
, &ft
);
6224 mono_array_set ((*data
), gint64
, 1, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
6225 tz_info
.DaylightDate
.wYear
= year
;
6226 convert_to_absolute_date(&tz_info
.DaylightDate
);
6227 err
= SystemTimeToFileTime (&tz_info
.DaylightDate
, &ft
);
6232 mono_array_set ((*data
), gint64
, 0, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
6234 mono_array_set ((*data
), gint64
, 2, (tz_info
.Bias
+ tz_info
.StandardBias
) * -600000000LL);
6235 mono_array_set ((*data
), gint64
, 3, (tz_info
.DaylightBias
- tz_info
.StandardBias
) * -600000000LL);
6242 ves_icall_System_Object_obj_address (MonoObject
*this)
6244 MONO_ARCH_SAVE_REGS
;
6251 static inline gint32
6252 mono_array_get_byte_length (MonoArray
*array
)
6258 klass
= array
->obj
.vtable
->klass
;
6260 if (array
->bounds
== NULL
)
6261 length
= array
->max_length
;
6264 for (i
= 0; i
< klass
->rank
; ++ i
)
6265 length
*= array
->bounds
[i
].length
;
6268 switch (klass
->element_class
->byval_arg
.type
) {
6271 case MONO_TYPE_BOOLEAN
:
6275 case MONO_TYPE_CHAR
:
6283 return length
* sizeof (gpointer
);
6294 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6296 MONO_ARCH_SAVE_REGS
;
6298 return mono_array_get_byte_length (array
);
6302 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6304 MONO_ARCH_SAVE_REGS
;
6306 return mono_array_get (array
, gint8
, idx
);
6310 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6312 MONO_ARCH_SAVE_REGS
;
6314 mono_array_set (array
, gint8
, idx
, value
);
6318 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6320 guint8
*src_buf
, *dest_buf
;
6322 MONO_ARCH_SAVE_REGS
;
6324 /* watch out for integer overflow */
6325 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6328 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6329 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6332 memcpy (dest_buf
, src_buf
, count
);
6334 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6340 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject
*this, MonoString
*class_name
)
6342 MonoDomain
*domain
= mono_object_domain (this);
6344 MonoRealProxy
*rp
= ((MonoRealProxy
*)this);
6345 MonoTransparentProxy
*tp
;
6349 MONO_ARCH_SAVE_REGS
;
6351 res
= mono_object_new (domain
, mono_defaults
.transparent_proxy_class
);
6352 tp
= (MonoTransparentProxy
*) res
;
6354 MONO_OBJECT_SETREF (tp
, rp
, rp
);
6355 type
= ((MonoReflectionType
*)rp
->class_to_proxy
)->type
;
6356 klass
= mono_class_from_mono_type (type
);
6358 tp
->custom_type_info
= (mono_object_isinst (this, mono_defaults
.iremotingtypeinfo_class
) != NULL
);
6359 tp
->remote_class
= mono_remote_class (domain
, class_name
, klass
);
6361 res
->vtable
= mono_remote_class_vtable (domain
, tp
->remote_class
, rp
);
6365 static MonoReflectionType
*
6366 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6368 return mono_type_get_object (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
);
6371 /* System.Environment */
6374 ves_icall_System_Environment_get_UserName (void)
6376 MONO_ARCH_SAVE_REGS
;
6378 /* using glib is more portable */
6379 return mono_string_new (mono_domain_get (), g_get_user_name ());
6384 ves_icall_System_Environment_get_MachineName (void)
6386 #if defined (PLATFORM_WIN32)
6391 len
= MAX_COMPUTERNAME_LENGTH
+ 1;
6392 buf
= g_new (gunichar2
, len
);
6395 if (GetComputerName (buf
, (PDWORD
) &len
))
6396 result
= mono_string_new_utf16 (mono_domain_get (), buf
, len
);
6400 #elif !defined(DISABLE_SOCKETS)
6404 if (gethostname (buf
, sizeof (buf
)) == 0)
6405 result
= mono_string_new (mono_domain_get (), buf
);
6411 return mono_string_new (mono_domain_get (), "mono");
6416 ves_icall_System_Environment_get_Platform (void)
6418 #if defined (PLATFORM_WIN32)
6421 #elif defined(__MACH__)
6423 if (mono_framework_version () < 2)
6427 // For compatibility with our client code, this will be 4 for a while.
6428 // We will eventually move to 6 to match .NET, but it requires all client
6429 // code to be updated and the documentation everywhere to be updated
6435 if (mono_framework_version () < 2)
6442 ves_icall_System_Environment_get_NewLine (void)
6444 MONO_ARCH_SAVE_REGS
;
6446 #if defined (PLATFORM_WIN32)
6447 return mono_string_new (mono_domain_get (), "\r\n");
6449 return mono_string_new (mono_domain_get (), "\n");
6454 ves_icall_System_Environment_GetEnvironmentVariable (MonoString
*name
)
6459 MONO_ARCH_SAVE_REGS
;
6464 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6465 value
= g_getenv (utf8_name
);
6472 return mono_string_new (mono_domain_get (), value
);
6476 * There is no standard way to get at environ.
6479 #ifndef __MINGW32_VERSION
6481 /* Apple defines this in crt_externs.h but doesn't provide that header for
6482 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6483 * in fact exist on all implementations (so far)
6485 gchar
***_NSGetEnviron();
6486 #define environ (*_NSGetEnviron())
6495 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6497 #ifdef PLATFORM_WIN32
6506 env_strings
= GetEnvironmentStrings();
6509 env_string
= env_strings
;
6510 while (*env_string
!= '\0') {
6511 /* weird case that MS seems to skip */
6512 if (*env_string
!= '=')
6514 while (*env_string
!= '\0')
6520 domain
= mono_domain_get ();
6521 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6525 env_string
= env_strings
;
6526 while (*env_string
!= '\0') {
6527 /* weird case that MS seems to skip */
6528 if (*env_string
!= '=') {
6529 equal_str
= wcschr(env_string
, '=');
6530 g_assert(equal_str
);
6531 str
= mono_string_new_utf16 (domain
, env_string
, equal_str
-env_string
);
6532 mono_array_setref (names
, n
, str
);
6535 while (*env_string
!= '\0')
6540 FreeEnvironmentStrings (env_strings
);
6552 MONO_ARCH_SAVE_REGS
;
6555 for (e
= environ
; *e
!= 0; ++ e
)
6558 domain
= mono_domain_get ();
6559 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6562 for (e
= environ
; *e
!= 0; ++ e
) {
6563 parts
= g_strsplit (*e
, "=", 2);
6565 str
= mono_string_new (domain
, *parts
);
6566 mono_array_setref (names
, n
, str
);
6579 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6581 #if !GLIB_CHECK_VERSION(2,4,0)
6582 #define g_setenv(a,b,c) setenv(a,b,c)
6583 #define g_unsetenv(a) unsetenv(a)
6587 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6589 #ifdef PLATFORM_WIN32
6590 gunichar2
*utf16_name
, *utf16_value
;
6592 gchar
*utf8_name
, *utf8_value
;
6595 MONO_ARCH_SAVE_REGS
;
6597 #ifdef PLATFORM_WIN32
6598 utf16_name
= mono_string_to_utf16 (name
);
6599 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6600 SetEnvironmentVariable (utf16_name
, NULL
);
6601 g_free (utf16_name
);
6605 utf16_value
= mono_string_to_utf16 (value
);
6607 SetEnvironmentVariable (utf16_name
, utf16_value
);
6609 g_free (utf16_name
);
6610 g_free (utf16_value
);
6612 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6614 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6615 g_unsetenv (utf8_name
);
6620 utf8_value
= mono_string_to_utf8 (value
);
6621 g_setenv (utf8_name
, utf8_value
, TRUE
);
6624 g_free (utf8_value
);
6629 ves_icall_System_Environment_Exit (int result
)
6631 MONO_ARCH_SAVE_REGS
;
6633 mono_threads_set_shutting_down ();
6635 mono_runtime_set_shutting_down ();
6637 /* Suspend all managed threads since the runtime is going away */
6638 mono_thread_suspend_all_other_threads ();
6640 mono_runtime_quit ();
6642 /* we may need to do some cleanup here... */
6647 ves_icall_System_Environment_GetGacPath (void)
6649 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6653 ves_icall_System_Environment_GetWindowsFolderPath (int folder
)
6655 #if defined (PLATFORM_WIN32)
6656 #ifndef CSIDL_FLAG_CREATE
6657 #define CSIDL_FLAG_CREATE 0x8000
6660 WCHAR path
[MAX_PATH
];
6661 /* Create directory if no existing */
6662 if (SUCCEEDED (SHGetFolderPathW (NULL
, folder
| CSIDL_FLAG_CREATE
, NULL
, 0, path
))) {
6666 return mono_string_new_utf16 (mono_domain_get (), path
, len
);
6669 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6671 return mono_string_new (mono_domain_get (), "");
6675 ves_icall_System_Environment_GetLogicalDrives (void)
6677 gunichar2 buf
[128], *ptr
, *dname
;
6679 guint initial_size
= 127, size
= 128;
6682 MonoString
*drivestr
;
6683 MonoDomain
*domain
= mono_domain_get ();
6686 MONO_ARCH_SAVE_REGS
;
6691 while (size
> initial_size
) {
6692 size
= (guint
) GetLogicalDriveStrings (initial_size
, ptr
);
6693 if (size
> initial_size
) {
6696 ptr
= g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6697 initial_size
= size
;
6711 result
= mono_array_new (domain
, mono_defaults
.string_class
, ndrives
);
6716 while (*u16
) { u16
++; len
++; }
6717 drivestr
= mono_string_new_utf16 (domain
, dname
, len
);
6718 mono_array_setref (result
, ndrives
++, drivestr
);
6729 ves_icall_System_Environment_InternalGetHome (void)
6731 MONO_ARCH_SAVE_REGS
;
6733 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6736 static const char *encodings
[] = {
6738 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6739 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6740 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6742 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6743 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6744 "x_unicode_2_0_utf_7",
6746 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6747 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6749 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6752 "unicodefffe", "utf_16be",
6759 * Returns the internal codepage, if the value of "int_code_page" is
6760 * 1 at entry, and we can not compute a suitable code page number,
6761 * returns the code page as a string
6764 ves_icall_System_Text_Encoding_InternalCodePage (gint32
*int_code_page
)
6769 char *codepage
= NULL
;
6771 int want_name
= *int_code_page
;
6774 *int_code_page
= -1;
6775 MONO_ARCH_SAVE_REGS
;
6777 g_get_charset (&cset
);
6778 c
= codepage
= strdup (cset
);
6779 for (c
= codepage
; *c
; c
++){
6780 if (isascii (*c
) && isalpha (*c
))
6785 /* g_print ("charset: %s\n", cset); */
6787 /* handle some common aliases */
6790 for (i
= 0; p
!= 0; ){
6791 if ((gssize
) p
< 7){
6793 p
= encodings
[++i
];
6796 if (strcmp (p
, codepage
) == 0){
6797 *int_code_page
= code
;
6800 p
= encodings
[++i
];
6803 if (strstr (codepage
, "utf_8") != NULL
)
6804 *int_code_page
|= 0x10000000;
6807 if (want_name
&& *int_code_page
== -1)
6808 return mono_string_new (mono_domain_get (), cset
);
6814 ves_icall_System_Environment_get_HasShutdownStarted (void)
6816 if (mono_runtime_is_shutting_down ())
6819 if (mono_domain_is_unloading (mono_domain_get ()))
6826 ves_icall_System_Environment_BroadcastSettingChange (void)
6828 #ifdef PLATFORM_WIN32
6829 SendMessageTimeout (HWND_BROADCAST
, WM_SETTINGCHANGE
, NULL
, L
"Environment", SMTO_ABORTIFHUNG
, 2000, 0);
6834 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage
*this,
6835 MonoReflectionMethod
*method
,
6836 MonoArray
*out_args
)
6838 MONO_ARCH_SAVE_REGS
;
6840 mono_message_init (mono_object_domain (this), this, method
, out_args
);
6844 ves_icall_IsTransparentProxy (MonoObject
*proxy
)
6846 MONO_ARCH_SAVE_REGS
;
6851 if (proxy
->vtable
->klass
== mono_defaults
.transparent_proxy_class
)
6857 static MonoReflectionMethod
*
6858 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6859 MonoReflectionType
*rtype
, MonoReflectionMethod
*rmethod
)
6863 MonoMethod
**vtable
;
6864 MonoMethod
*res
= NULL
;
6866 MONO_CHECK_ARG_NULL (rtype
);
6867 MONO_CHECK_ARG_NULL (rmethod
);
6869 method
= rmethod
->method
;
6870 klass
= mono_class_from_mono_type (rtype
->type
);
6872 if (MONO_CLASS_IS_INTERFACE (klass
))
6875 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
6878 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
6879 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
6885 mono_class_setup_vtable (klass
);
6886 vtable
= klass
->vtable
;
6888 if (method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
) {
6889 int offs
= mono_class_interface_offset (klass
, method
->klass
);
6891 res
= vtable
[offs
+ method
->slot
];
6893 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
6896 if (method
->slot
!= -1)
6897 res
= vtable
[method
->slot
];
6903 return mono_method_get_object (mono_domain_get (), res
, NULL
);
6907 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType
*type
, MonoBoolean enable
)
6912 MONO_ARCH_SAVE_REGS
;
6914 klass
= mono_class_from_mono_type (type
->type
);
6915 vtable
= mono_class_vtable (mono_domain_get (), klass
);
6917 if (enable
) vtable
->remote
= 1;
6918 else vtable
->remote
= 0;
6922 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType
*type
)
6927 MONO_ARCH_SAVE_REGS
;
6929 domain
= mono_object_domain (type
);
6930 klass
= mono_class_from_mono_type (type
->type
);
6932 if (klass
->rank
>= 1) {
6933 g_assert (klass
->rank
== 1);
6934 return (MonoObject
*) mono_array_new (domain
, klass
->element_class
, 0);
6936 /* Bypass remoting object creation check */
6937 return mono_object_new_alloc_specific (mono_class_vtable (domain
, klass
));
6942 ves_icall_System_IO_get_temp_path (void)
6944 MONO_ARCH_SAVE_REGS
;
6946 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6949 #ifndef PLATFORM_NO_DRIVEINFO
6951 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString
*path_name
, guint64
*free_bytes_avail
,
6952 guint64
*total_number_of_bytes
, guint64
*total_number_of_free_bytes
,
6956 ULARGE_INTEGER wapi_free_bytes_avail
;
6957 ULARGE_INTEGER wapi_total_number_of_bytes
;
6958 ULARGE_INTEGER wapi_total_number_of_free_bytes
;
6960 MONO_ARCH_SAVE_REGS
;
6962 *error
= ERROR_SUCCESS
;
6963 result
= GetDiskFreeSpaceEx (mono_string_chars (path_name
), &wapi_free_bytes_avail
, &wapi_total_number_of_bytes
,
6964 &wapi_total_number_of_free_bytes
);
6967 *free_bytes_avail
= wapi_free_bytes_avail
.QuadPart
;
6968 *total_number_of_bytes
= wapi_total_number_of_bytes
.QuadPart
;
6969 *total_number_of_free_bytes
= wapi_total_number_of_free_bytes
.QuadPart
;
6971 *free_bytes_avail
= 0;
6972 *total_number_of_bytes
= 0;
6973 *total_number_of_free_bytes
= 0;
6974 *error
= GetLastError ();
6981 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString
*root_path_name
)
6983 MONO_ARCH_SAVE_REGS
;
6985 return GetDriveType (mono_string_chars (root_path_name
));
6990 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod
*method
)
6992 MONO_ARCH_SAVE_REGS
;
6994 return mono_compile_method (method
);
6998 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7003 MONO_ARCH_SAVE_REGS
;
7005 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
7007 #if defined (PLATFORM_WIN32)
7008 /* Avoid mixing '/' and '\\' */
7011 for (i
= strlen (path
) - 1; i
>= 0; i
--)
7012 if (path
[i
] == '/')
7016 mcpath
= mono_string_new (mono_domain_get (), path
);
7023 get_bundled_machine_config (void)
7025 const gchar
*machine_config
;
7027 MONO_ARCH_SAVE_REGS
;
7029 machine_config
= mono_get_machine_config ();
7031 if (!machine_config
)
7034 return mono_string_new (mono_domain_get (), machine_config
);
7038 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7043 MONO_ARCH_SAVE_REGS
;
7045 path
= g_path_get_dirname (mono_get_config_dir ());
7047 #if defined (PLATFORM_WIN32)
7048 /* Avoid mixing '/' and '\\' */
7051 for (i
= strlen (path
) - 1; i
>= 0; i
--)
7052 if (path
[i
] == '/')
7056 ipath
= mono_string_new (mono_domain_get (), path
);
7063 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7065 return mono_debug_using_mono_debugger ();
7069 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
7071 #if defined (PLATFORM_WIN32)
7072 OutputDebugString (mono_string_chars (message
));
7074 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
7078 /* Only used for value types */
7080 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType
*type
)
7085 MONO_ARCH_SAVE_REGS
;
7087 domain
= mono_object_domain (type
);
7088 klass
= mono_class_from_mono_type (type
->type
);
7090 if (mono_class_is_nullable (klass
))
7091 /* No arguments -> null */
7094 return mono_object_new (domain
, klass
);
7097 static MonoReflectionMethod
*
7098 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod
*m
)
7100 MonoClass
*klass
, *parent
;
7101 MonoMethod
*method
= m
->method
;
7102 MonoMethod
*result
= NULL
;
7104 MONO_ARCH_SAVE_REGS
;
7106 if (method
->klass
== NULL
)
7109 if (!(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
) ||
7110 MONO_CLASS_IS_INTERFACE (method
->klass
) ||
7111 method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
)
7114 klass
= method
->klass
;
7115 if (klass
->generic_class
)
7116 klass
= klass
->generic_class
->container_class
;
7118 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7119 for (parent
= klass
->parent
; parent
!= NULL
; parent
= parent
->parent
) {
7120 mono_class_setup_vtable (parent
);
7121 if (parent
->vtable_size
<= method
->slot
)
7126 if (klass
== method
->klass
)
7129 result
= klass
->vtable
[method
->slot
];
7130 if (result
== NULL
) {
7131 /* It is an abstract method */
7132 gpointer iter
= NULL
;
7133 while ((result
= mono_class_get_methods (klass
, &iter
)))
7134 if (result
->slot
== method
->slot
)
7141 return mono_method_get_object (mono_domain_get (), result
, NULL
);
7145 ves_icall_MonoMethod_get_name (MonoReflectionMethod
*m
)
7147 MonoMethod
*method
= m
->method
;
7149 MONO_OBJECT_SETREF (m
, name
, mono_string_new (mono_object_domain (m
), method
->name
));
7154 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
7156 MONO_ARCH_SAVE_REGS
;
7158 iter
->sig
= *(MonoMethodSignature
**)argsp
;
7160 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
7161 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
7164 /* FIXME: it's not documented what start is exactly... */
7168 guint32 i
, arg_size
;
7170 iter
->args
= argsp
+ sizeof (gpointer
);
7171 #ifndef MONO_ARCH_REGPARMS
7172 for (i
= 0; i
< iter
->sig
->sentinelpos
; ++i
) {
7173 arg_size
= mono_type_stack_size (iter
->sig
->params
[i
], &align
);
7174 iter
->args
= (char*)iter
->args
+ arg_size
;
7178 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
7180 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7184 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
7186 guint32 i
, arg_size
;
7189 MONO_ARCH_SAVE_REGS
;
7191 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7193 g_assert (i
< iter
->sig
->param_count
);
7195 res
.type
= iter
->sig
->params
[i
];
7196 res
.klass
= mono_class_from_mono_type (res
.type
);
7197 res
.value
= iter
->args
;
7198 arg_size
= mono_type_stack_size (res
.type
, &align
);
7199 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7200 if (arg_size
<= sizeof (gpointer
)) {
7202 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
7203 res
.value
= (guint8
*)res
.value
+ padding
;
7206 iter
->args
= (char*)iter
->args
+ arg_size
;
7209 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7215 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
7217 guint32 i
, arg_size
;
7220 MONO_ARCH_SAVE_REGS
;
7222 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7224 g_assert (i
< iter
->sig
->param_count
);
7226 while (i
< iter
->sig
->param_count
) {
7227 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
7229 res
.type
= iter
->sig
->params
[i
];
7230 res
.klass
= mono_class_from_mono_type (res
.type
);
7231 /* FIXME: endianess issue... */
7232 res
.value
= iter
->args
;
7233 arg_size
= mono_type_stack_size (res
.type
, &align
);
7234 iter
->args
= (char*)iter
->args
+ arg_size
;
7236 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7239 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7248 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7251 MONO_ARCH_SAVE_REGS
;
7253 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7255 g_assert (i
< iter
->sig
->param_count
);
7257 return iter
->sig
->params
[i
];
7261 mono_TypedReference_ToObject (MonoTypedRef tref
)
7263 MONO_ARCH_SAVE_REGS
;
7265 if (MONO_TYPE_IS_REFERENCE (tref
.type
)) {
7266 MonoObject
** objp
= tref
.value
;
7270 return mono_value_box (mono_domain_get (), tref
.klass
, tref
.value
);
7274 mono_TypedReference_ToObjectInternal (MonoType
*type
, gpointer value
, MonoClass
*klass
)
7276 MONO_ARCH_SAVE_REGS
;
7278 if (MONO_TYPE_IS_REFERENCE (type
)) {
7279 MonoObject
** objp
= value
;
7283 return mono_value_box (mono_domain_get (), klass
, value
);
7287 prelink_method (MonoMethod
*method
)
7289 const char *exc_class
, *exc_arg
;
7290 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7292 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7294 mono_raise_exception(
7295 mono_exception_from_name_msg (mono_defaults
.corlib
, "System", exc_class
, exc_arg
) );
7297 /* create the wrapper, too? */
7301 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod
*method
)
7303 MONO_ARCH_SAVE_REGS
;
7304 prelink_method (method
->method
);
7308 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
*type
)
7310 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
7312 gpointer iter
= NULL
;
7313 MONO_ARCH_SAVE_REGS
;
7315 while ((m
= mono_class_get_methods (klass
, &iter
)))
7319 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7321 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7322 gint32
const **exponents
,
7323 gunichar2
const **digitLowerTable
,
7324 gunichar2
const **digitUpperTable
,
7325 gint64
const **tenPowersList
,
7326 gint32
const **decHexDigits
)
7328 *mantissas
= Formatter_MantissaBitsTable
;
7329 *exponents
= Formatter_TensExponentTable
;
7330 *digitLowerTable
= Formatter_DigitLowerTable
;
7331 *digitUpperTable
= Formatter_DigitUpperTable
;
7332 *tenPowersList
= Formatter_TenPowersList
;
7333 *decHexDigits
= Formatter_DecHexDigits
;
7336 /* These parameters are "readonly" in corlib/System/Char.cs */
7338 ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data
,
7339 guint8
const **numeric_data
,
7340 gdouble
const **numeric_data_values
,
7341 guint16
const **to_lower_data_low
,
7342 guint16
const **to_lower_data_high
,
7343 guint16
const **to_upper_data_low
,
7344 guint16
const **to_upper_data_high
)
7346 *category_data
= CategoryData
;
7347 *numeric_data
= NumericData
;
7348 *numeric_data_values
= NumericDataValues
;
7349 *to_lower_data_low
= ToLowerDataLow
;
7350 *to_lower_data_high
= ToLowerDataHigh
;
7351 *to_upper_data_low
= ToUpperDataLow
;
7352 *to_upper_data_high
= ToUpperDataHigh
;
7356 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod
*method
)
7358 return method
->method
->token
;
7362 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7363 * and avoid useless allocations.
7366 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
)
7370 for (i
= 0; i
< type
->num_mods
; ++i
) {
7371 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7376 res
= mono_array_new (mono_domain_get (), mono_defaults
.systemtype_class
, count
);
7378 for (i
= 0; i
< type
->num_mods
; ++i
) {
7379 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7380 MonoClass
*klass
= mono_class_get (image
, type
->modifiers
[i
].token
);
7381 mono_array_setref (res
, count
, mono_type_get_object (mono_domain_get (), &klass
->byval_arg
));
7389 param_info_get_type_modifiers (MonoReflectionParameter
*param
, MonoBoolean optional
)
7391 MonoType
*type
= param
->ClassImpl
->type
;
7392 MonoReflectionMethod
*method
= (MonoReflectionMethod
*)param
->MemberImpl
;
7393 MonoImage
*image
= method
->method
->klass
->image
;
7394 int pos
= param
->PositionImpl
;
7395 MonoMethodSignature
*sig
= mono_method_signature (method
->method
);
7399 type
= sig
->params
[pos
];
7401 return type_array_from_modifiers (image
, type
, optional
);
7405 get_property_type (MonoProperty
*prop
)
7407 MonoMethodSignature
*sig
;
7409 sig
= mono_method_signature (prop
->get
);
7411 } else if (prop
->set
) {
7412 sig
= mono_method_signature (prop
->set
);
7413 return sig
->params
[sig
->param_count
- 1];
7419 property_info_get_type_modifiers (MonoReflectionProperty
*property
, MonoBoolean optional
)
7421 MonoType
*type
= get_property_type (property
->property
);
7422 MonoImage
*image
= property
->klass
->image
;
7426 return type_array_from_modifiers (image
, type
, optional
);
7430 custom_attrs_defined_internal (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7432 MonoCustomAttrInfo
*cinfo
;
7435 cinfo
= mono_reflection_get_custom_attrs_info (obj
);
7438 found
= mono_custom_attrs_has_attr (cinfo
, mono_class_from_mono_type (attr_type
->type
));
7440 mono_custom_attrs_free (cinfo
);
7445 custom_attrs_get_by_type (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7447 MonoArray
*res
= mono_reflection_get_custom_attrs_by_type (obj
, attr_type
? mono_class_from_mono_type (attr_type
->type
) : NULL
);
7449 if (mono_loader_get_last_error ()) {
7450 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7451 g_assert_not_reached ();
7458 GCHandle_CheckCurrentDomain (guint32 gchandle
)
7460 return mono_gchandle_is_in_domain (gchandle
, mono_domain_get ());
7464 ves_icall_Mono_Runtime_GetDisplayName (void)
7466 static const char display_name_str
[] = "Mono " VERSION
;
7467 MonoString
*display_name
= mono_string_new (mono_domain_get (), display_name_str
);
7468 return display_name
;
7472 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code
)
7474 MonoString
*message
;
7478 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
7479 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, code
, 0,
7482 message
= mono_string_new (mono_domain_get (), "Error looking up error string");
7484 message
= mono_string_new_utf16 (mono_domain_get (), buf
, ret
);
7492 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7493 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7494 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7495 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7496 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7497 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7498 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7499 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7503 base64_to_byte_array (gunichar2
*start
, gint ilength
, MonoBoolean allowWhitespaceOnly
)
7508 gunichar2 last
, prev_last
, prev2_last
;
7516 last
= prev_last
= 0, prev2_last
= 0;
7517 for (i
= 0; i
< ilength
; i
++) {
7519 if (c
>= sizeof (dbase64
)) {
7520 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7521 "System", "FormatException",
7522 "Invalid character found.");
7523 mono_raise_exception (exc
);
7524 } else if (isspace (c
)) {
7527 prev2_last
= prev_last
;
7533 olength
= ilength
- ignored
;
7535 if (allowWhitespaceOnly
&& olength
== 0) {
7536 return mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, 0);
7539 if ((olength
& 3) != 0 || olength
<= 0) {
7540 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System",
7541 "FormatException", "Invalid length.");
7542 mono_raise_exception (exc
);
7545 if (prev2_last
== '=') {
7546 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7547 mono_raise_exception (exc
);
7550 olength
= (olength
* 3) / 4;
7554 if (prev_last
== '=')
7557 result
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, olength
);
7558 res_ptr
= mono_array_addr (result
, guchar
, 0);
7559 for (i
= 0; i
< ilength
; ) {
7562 for (k
= 0; k
< 4 && i
< ilength
;) {
7568 if (((b
[k
] = dbase64
[c
]) & 0x80) != 0) {
7569 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7570 "System", "FormatException",
7571 "Invalid character found.");
7572 mono_raise_exception (exc
);
7577 *res_ptr
++ = (b
[0] << 2) | (b
[1] >> 4);
7579 *res_ptr
++ = (b
[1] << 4) | (b
[2] >> 2);
7581 *res_ptr
++ = (b
[2] << 6) | b
[3];
7583 while (i
< ilength
&& isspace (start
[i
]))
7591 InternalFromBase64String (MonoString
*str
, MonoBoolean allowWhitespaceOnly
)
7593 MONO_ARCH_SAVE_REGS
;
7595 return base64_to_byte_array (mono_string_chars (str
),
7596 mono_string_length (str
), allowWhitespaceOnly
);
7600 InternalFromBase64CharArray (MonoArray
*input
, gint offset
, gint length
)
7602 MONO_ARCH_SAVE_REGS
;
7604 return base64_to_byte_array (mono_array_addr (input
, gunichar2
, offset
),
7608 #define ICALL_TYPE(id,name,first)
7609 #define ICALL(id,name,func) Icall_ ## id,
7612 #include "metadata/icall-def.h"
7618 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7619 #define ICALL(id,name,func)
7621 #include "metadata/icall-def.h"
7627 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7628 #define ICALL(id,name,func)
7630 guint16 first_icall
;
7633 static const IcallTypeDesc
7634 icall_type_descs
[] = {
7635 #include "metadata/icall-def.h"
7639 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7642 #define ICALL_TYPE(id,name,first)
7645 #ifdef HAVE_ARRAY_ELEM_INIT
7646 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7647 #define MSGSTRFIELD1(line) str##line
7649 static const struct msgstrtn_t
{
7650 #define ICALL(id,name,func)
7652 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7653 #include "metadata/icall-def.h"
7655 } icall_type_names_str
= {
7656 #define ICALL_TYPE(id,name,first) (name),
7657 #include "metadata/icall-def.h"
7660 static const guint16 icall_type_names_idx
[] = {
7661 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7662 #include "metadata/icall-def.h"
7665 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7667 static const struct msgstr_t
{
7669 #define ICALL_TYPE(id,name,first)
7670 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7671 #include "metadata/icall-def.h"
7673 } icall_names_str
= {
7674 #define ICALL(id,name,func) (name),
7675 #include "metadata/icall-def.h"
7678 static const guint16 icall_names_idx
[] = {
7679 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7680 #include "metadata/icall-def.h"
7683 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7689 #define ICALL_TYPE(id,name,first) name,
7690 #define ICALL(id,name,func)
7691 static const char* const
7692 icall_type_names
[] = {
7693 #include "metadata/icall-def.h"
7697 #define icall_type_name_get(id) (icall_type_names [(id)])
7701 #define ICALL_TYPE(id,name,first)
7702 #define ICALL(id,name,func) name,
7703 static const char* const
7705 #include "metadata/icall-def.h"
7708 #define icall_name_get(id) icall_names [(id)]
7710 #endif /* !HAVE_ARRAY_ELEM_INIT */
7714 #define ICALL_TYPE(id,name,first)
7715 #define ICALL(id,name,func) func,
7716 static const gconstpointer
7717 icall_functions
[] = {
7718 #include "metadata/icall-def.h"
7722 static GHashTable
*icall_hash
= NULL
;
7723 static GHashTable
*jit_icall_hash_name
= NULL
;
7724 static GHashTable
*jit_icall_hash_addr
= NULL
;
7727 mono_icall_init (void)
7731 /* check that tables are sorted: disable in release */
7734 const char *prev_class
= NULL
;
7735 const char *prev_method
;
7737 for (i
= 0; i
< Icall_type_num
; ++i
) {
7738 const IcallTypeDesc
*desc
;
7741 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
7742 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
7743 prev_class
= icall_type_name_get (i
);
7744 desc
= &icall_type_descs
[i
];
7745 num_icalls
= icall_desc_num_icalls (desc
);
7746 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7747 for (j
= 0; j
< num_icalls
; ++j
) {
7748 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
7749 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
7750 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
7751 prev_method
= methodn
;
7756 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
7760 mono_icall_cleanup (void)
7762 g_hash_table_destroy (icall_hash
);
7763 g_hash_table_destroy (jit_icall_hash_name
);
7764 g_hash_table_destroy (jit_icall_hash_addr
);
7768 mono_add_internal_call (const char *name
, gconstpointer method
)
7770 mono_loader_lock ();
7772 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
7774 mono_loader_unlock ();
7777 #ifdef HAVE_ARRAY_ELEM_INIT
7779 compare_method_imap (const void *key
, const void *elem
)
7781 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
7782 return strcmp (key
, method_name
);
7786 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7788 const guint16
*nameslot
= bsearch (name
, icall_names_idx
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names_idx
[0]), compare_method_imap
);
7791 return (gpointer
)icall_functions
[(nameslot
- &icall_names_idx
[0])];
7795 compare_class_imap (const void *key
, const void *elem
)
7797 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
7798 return strcmp (key
, class_name
);
7801 static const IcallTypeDesc
*
7802 find_class_icalls (const char *name
)
7804 const guint16
*nameslot
= bsearch (name
, icall_type_names_idx
, Icall_type_num
, sizeof (icall_type_names_idx
[0]), compare_class_imap
);
7807 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
7812 compare_method_imap (const void *key
, const void *elem
)
7814 const char** method_name
= (const char**)elem
;
7815 return strcmp (key
, *method_name
);
7819 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7821 const char **nameslot
= bsearch (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
7824 return (gpointer
)icall_functions
[(nameslot
- icall_names
)];
7828 compare_class_imap (const void *key
, const void *elem
)
7830 const char** class_name
= (const char**)elem
;
7831 return strcmp (key
, *class_name
);
7834 static const IcallTypeDesc
*
7835 find_class_icalls (const char *name
)
7837 const char **nameslot
= bsearch (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
7840 return &icall_type_descs
[nameslot
- icall_type_names
];
7846 * we should probably export this as an helper (handle nested types).
7847 * Returns the number of chars written in buf.
7850 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
7852 int nspacelen
, cnamelen
;
7853 nspacelen
= strlen (klass
->name_space
);
7854 cnamelen
= strlen (klass
->name
);
7855 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
7858 memcpy (buf
, klass
->name_space
, nspacelen
);
7859 buf
[nspacelen
++] = '.';
7861 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
7862 buf
[nspacelen
+ cnamelen
] = 0;
7863 return nspacelen
+ cnamelen
;
7867 mono_lookup_internal_call (MonoMethod
*method
)
7872 int typelen
= 0, mlen
, siglen
;
7874 const IcallTypeDesc
*imap
;
7876 g_assert (method
!= NULL
);
7878 if (method
->is_inflated
)
7879 method
= ((MonoMethodInflated
*) method
)->declaring
;
7881 if (method
->klass
->nested_in
) {
7882 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
7886 mname
[pos
++] = '/';
7889 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
7895 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
7900 imap
= find_class_icalls (mname
);
7902 mname
[typelen
] = ':';
7903 mname
[typelen
+ 1] = ':';
7905 mlen
= strlen (method
->name
);
7906 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
7907 sigstart
= mname
+ typelen
+ 2 + mlen
;
7910 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
7911 siglen
= strlen (tmpsig
);
7912 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
7915 memcpy (sigstart
+ 1, tmpsig
, siglen
);
7916 sigstart
[siglen
+ 1] = ')';
7917 sigstart
[siglen
+ 2] = 0;
7920 mono_loader_lock ();
7922 res
= g_hash_table_lookup (icall_hash
, mname
);
7924 mono_loader_unlock ();
7927 /* try without signature */
7929 res
= g_hash_table_lookup (icall_hash
, mname
);
7931 mono_loader_unlock ();
7935 /* it wasn't found in the static call tables */
7937 mono_loader_unlock ();
7940 res
= find_method_icall (imap
, sigstart
- mlen
);
7942 mono_loader_unlock ();
7945 /* try _with_ signature */
7947 res
= find_method_icall (imap
, sigstart
- mlen
);
7949 mono_loader_unlock ();
7953 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
7954 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7955 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
7956 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7957 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");
7958 g_print ("If you see other errors or faults after this message they are probably related\n");
7959 g_print ("and you need to fix your mono install first.\n");
7961 mono_loader_unlock ();
7967 type_from_typename (char *typename
)
7969 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
7971 if (!strcmp (typename
, "int"))
7972 klass
= mono_defaults
.int_class
;
7973 else if (!strcmp (typename
, "ptr"))
7974 klass
= mono_defaults
.int_class
;
7975 else if (!strcmp (typename
, "void"))
7976 klass
= mono_defaults
.void_class
;
7977 else if (!strcmp (typename
, "int32"))
7978 klass
= mono_defaults
.int32_class
;
7979 else if (!strcmp (typename
, "uint32"))
7980 klass
= mono_defaults
.uint32_class
;
7981 else if (!strcmp (typename
, "int8"))
7982 klass
= mono_defaults
.sbyte_class
;
7983 else if (!strcmp (typename
, "uint8"))
7984 klass
= mono_defaults
.byte_class
;
7985 else if (!strcmp (typename
, "int16"))
7986 klass
= mono_defaults
.int16_class
;
7987 else if (!strcmp (typename
, "uint16"))
7988 klass
= mono_defaults
.uint16_class
;
7989 else if (!strcmp (typename
, "long"))
7990 klass
= mono_defaults
.int64_class
;
7991 else if (!strcmp (typename
, "ulong"))
7992 klass
= mono_defaults
.uint64_class
;
7993 else if (!strcmp (typename
, "float"))
7994 klass
= mono_defaults
.single_class
;
7995 else if (!strcmp (typename
, "double"))
7996 klass
= mono_defaults
.double_class
;
7997 else if (!strcmp (typename
, "object"))
7998 klass
= mono_defaults
.object_class
;
7999 else if (!strcmp (typename
, "obj"))
8000 klass
= mono_defaults
.object_class
;
8001 else if (!strcmp (typename
, "string"))
8002 klass
= mono_defaults
.string_class
;
8003 else if (!strcmp (typename
, "bool"))
8004 klass
= mono_defaults
.boolean_class
;
8005 else if (!strcmp (typename
, "boolean"))
8006 klass
= mono_defaults
.boolean_class
;
8008 g_error ("%s", typename
);
8009 g_assert_not_reached ();
8011 return &klass
->byval_arg
;
8014 MonoMethodSignature
*
8015 mono_create_icall_signature (const char *sigstr
)
8020 MonoMethodSignature
*res
;
8022 mono_loader_lock ();
8023 res
= g_hash_table_lookup (mono_defaults
.corlib
->helper_signatures
, sigstr
);
8025 mono_loader_unlock ();
8029 parts
= g_strsplit (sigstr
, " ", 256);
8038 res
= mono_metadata_signature_alloc (mono_defaults
.corlib
, len
- 1);
8041 #ifdef PLATFORM_WIN32
8043 * Under windows, the default pinvoke calling convention is STDCALL but
8046 res
->call_convention
= MONO_CALL_C
;
8049 res
->ret
= type_from_typename (parts
[0]);
8050 for (i
= 1; i
< len
; ++i
) {
8051 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
8056 g_hash_table_insert (mono_defaults
.corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
8058 mono_loader_unlock ();
8064 mono_find_jit_icall_by_name (const char *name
)
8066 MonoJitICallInfo
*info
;
8067 g_assert (jit_icall_hash_name
);
8069 mono_loader_lock ();
8070 info
= g_hash_table_lookup (jit_icall_hash_name
, name
);
8071 mono_loader_unlock ();
8076 mono_find_jit_icall_by_addr (gconstpointer addr
)
8078 MonoJitICallInfo
*info
;
8079 g_assert (jit_icall_hash_addr
);
8081 mono_loader_lock ();
8082 info
= g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
8083 mono_loader_unlock ();
8089 * mono_get_jit_icall_info:
8091 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8092 * caller should access it while holding the loader lock.
8095 mono_get_jit_icall_info (void)
8097 return jit_icall_hash_name
;
8101 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
8103 mono_loader_lock ();
8104 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
8105 mono_loader_unlock ();
8109 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
8111 MonoJitICallInfo
*info
;
8116 mono_loader_lock ();
8118 if (!jit_icall_hash_name
) {
8119 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
8120 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
8123 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
8124 g_warning ("jit icall already defined \"%s\"\n", name
);
8125 g_assert_not_reached ();
8128 info
= g_new0 (MonoJitICallInfo
, 1);
8135 info
->wrapper
= func
;
8137 info
->wrapper
= NULL
;
8140 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
8141 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
8143 mono_loader_unlock ();