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 (HOST_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>
75 #include <mono/utils/mono-string.h>
76 #include <mono/utils/mono-error-internals.h>
77 #include <mono/utils/mono-mmap.h>
79 #if defined (HOST_WIN32)
85 extern MonoString
* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL
;
87 static MonoReflectionAssembly
* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
90 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
);
92 /* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
93 * It works by allocating an initial small array on stack and only going to malloc'd memory if needed.
101 #define MONO_PTR_ARRAY_MAX_ON_STACK (16)
103 #define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
105 (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
106 (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
109 #define mono_ptr_array_destroy(ARRAY) do {\
110 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
111 mono_gc_free_fixed ((ARRAY).data); \
114 #define mono_ptr_array_append(ARRAY, VALUE) do { \
115 if ((ARRAY).size >= (ARRAY).capacity) {\
116 void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
117 memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
118 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
119 mono_gc_free_fixed ((ARRAY).data); \
120 (ARRAY).data = __tmp; \
121 (ARRAY).capacity *= 2;\
123 ((ARRAY).data [(ARRAY).size++] = VALUE); \
126 #define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
127 ((ARRAY).data [(IDX)] = VALUE); \
130 #define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
132 #define mono_ptr_array_size(ARRAY) ((ARRAY).size)
135 static inline MonoBoolean
136 is_generic_parameter (MonoType
*type
)
138 return !type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
);
142 * We expect a pointer to a char, not a string
145 mono_double_ParseImpl (char *ptr
, double *result
)
147 gchar
*endptr
= NULL
;
154 *result
= strtod (ptr
, &endptr
);
158 /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
159 EnterCriticalSection (&mono_strtod_mutex
);
160 *result
= mono_strtod (ptr
, &endptr
);
161 LeaveCriticalSection (&mono_strtod_mutex
);
163 *result
= mono_strtod (ptr
, &endptr
);
168 if (!*ptr
|| (endptr
&& *endptr
))
175 ves_icall_System_Array_GetValueImpl (MonoObject
*this, guint32 pos
)
184 ao
= (MonoArray
*)this;
185 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
187 esize
= mono_array_element_size (ac
);
188 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
190 if (ac
->element_class
->valuetype
)
191 return mono_value_box (this->vtable
->domain
, ac
->element_class
, ea
);
197 ves_icall_System_Array_GetValue (MonoObject
*this, MonoObject
*idxs
)
205 MONO_CHECK_ARG_NULL (idxs
);
207 io
= (MonoArray
*)idxs
;
208 ic
= (MonoClass
*)io
->obj
.vtable
->klass
;
210 ao
= (MonoArray
*)this;
211 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
213 g_assert (ic
->rank
== 1);
214 if (io
->bounds
!= NULL
|| io
->max_length
!= ac
->rank
)
215 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
217 ind
= (gint32
*)io
->vector
;
219 if (ao
->bounds
== NULL
) {
220 if (*ind
< 0 || *ind
>= ao
->max_length
)
221 mono_raise_exception (mono_get_exception_index_out_of_range ());
223 return ves_icall_System_Array_GetValueImpl (this, *ind
);
226 for (i
= 0; i
< ac
->rank
; i
++)
227 if ((ind
[i
] < ao
->bounds
[i
].lower_bound
) ||
228 (ind
[i
] >= (mono_array_lower_bound_t
)ao
->bounds
[i
].length
+ ao
->bounds
[i
].lower_bound
))
229 mono_raise_exception (mono_get_exception_index_out_of_range ());
231 pos
= ind
[0] - ao
->bounds
[0].lower_bound
;
232 for (i
= 1; i
< ac
->rank
; i
++)
233 pos
= pos
*ao
->bounds
[i
].length
+ ind
[i
] -
234 ao
->bounds
[i
].lower_bound
;
236 return ves_icall_System_Array_GetValueImpl (this, pos
);
240 ves_icall_System_Array_SetValueImpl (MonoArray
*this, MonoObject
*value
, guint32 pos
)
242 MonoClass
*ac
, *vc
, *ec
;
254 vc
= value
->vtable
->klass
;
258 ac
= this->obj
.vtable
->klass
;
259 ec
= ac
->element_class
;
261 esize
= mono_array_element_size (ac
);
262 ea
= (gpointer
*)((char*)this->vector
+ (pos
* esize
));
263 va
= (gpointer
*)((char*)value
+ sizeof (MonoObject
));
265 if (mono_class_is_nullable (ec
)) {
266 mono_nullable_init ((guint8
*)ea
, value
, ec
);
271 memset (ea
, 0, esize
);
275 #define NO_WIDENING_CONVERSION G_STMT_START{\
276 mono_raise_exception (mono_get_exception_argument ( \
277 "value", "not a widening conversion")); \
280 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
281 if (esize < vsize + (extra)) \
282 mono_raise_exception (mono_get_exception_argument ( \
283 "value", "not a widening conversion")); \
286 #define INVALID_CAST G_STMT_START{\
287 mono_raise_exception (mono_get_exception_invalid_cast ()); \
290 /* Check element (destination) type. */
291 switch (ec
->byval_arg
.type
) {
292 case MONO_TYPE_STRING
:
293 switch (vc
->byval_arg
.type
) {
294 case MONO_TYPE_STRING
:
300 case MONO_TYPE_BOOLEAN
:
301 switch (vc
->byval_arg
.type
) {
302 case MONO_TYPE_BOOLEAN
:
315 NO_WIDENING_CONVERSION
;
322 if (!ec
->valuetype
) {
323 if (!mono_object_isinst (value
, ec
))
325 mono_gc_wbarrier_set_arrayref (this, ea
, (MonoObject
*)value
);
329 if (mono_object_isinst (value
, ec
)) {
330 if (ec
->has_references
)
331 mono_value_copy (ea
, (char*)value
+ sizeof (MonoObject
), ec
);
333 memcpy (ea
, (char *)value
+ sizeof (MonoObject
), esize
);
340 vsize
= mono_class_instance_size (vc
) - sizeof (MonoObject
);
342 et
= ec
->byval_arg
.type
;
343 if (et
== MONO_TYPE_VALUETYPE
&& ec
->byval_arg
.data
.klass
->enumtype
)
344 et
= mono_class_enum_basetype (ec
->byval_arg
.data
.klass
)->type
;
346 vt
= vc
->byval_arg
.type
;
347 if (vt
== MONO_TYPE_VALUETYPE
&& vc
->byval_arg
.data
.klass
->enumtype
)
348 vt
= mono_class_enum_basetype (vc
->byval_arg
.data
.klass
)->type
;
350 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
356 case MONO_TYPE_CHAR: \
357 CHECK_WIDENING_CONVERSION(0); \
358 *(etype *) ea = (etype) u64; \
360 /* You can't assign a signed value to an unsigned array. */ \
365 /* You can't assign a floating point number to an integer array. */ \
368 NO_WIDENING_CONVERSION; \
372 #define ASSIGN_SIGNED(etype) G_STMT_START{\
378 CHECK_WIDENING_CONVERSION(0); \
379 *(etype *) ea = (etype) i64; \
381 /* You can assign an unsigned value to a signed array if the array's */ \
382 /* element size is larger than the value size. */ \
387 case MONO_TYPE_CHAR: \
388 CHECK_WIDENING_CONVERSION(1); \
389 *(etype *) ea = (etype) u64; \
391 /* You can't assign a floating point number to an integer array. */ \
394 NO_WIDENING_CONVERSION; \
398 #define ASSIGN_REAL(etype) G_STMT_START{\
402 CHECK_WIDENING_CONVERSION(0); \
403 *(etype *) ea = (etype) r64; \
405 /* All integer values fit into a floating point array, so we don't */ \
406 /* need to CHECK_WIDENING_CONVERSION here. */ \
411 *(etype *) ea = (etype) i64; \
417 case MONO_TYPE_CHAR: \
418 *(etype *) ea = (etype) u64; \
425 u64
= *(guint8
*) va
;
428 u64
= *(guint16
*) va
;
431 u64
= *(guint32
*) va
;
434 u64
= *(guint64
*) va
;
440 i64
= *(gint16
*) va
;
443 i64
= *(gint32
*) va
;
446 i64
= *(gint64
*) va
;
449 r64
= *(gfloat
*) va
;
452 r64
= *(gdouble
*) va
;
455 u64
= *(guint16
*) va
;
457 case MONO_TYPE_BOOLEAN
:
458 /* Boolean is only compatible with itself. */
471 NO_WIDENING_CONVERSION
;
478 /* If we can't do a direct copy, let's try a widening conversion. */
481 ASSIGN_UNSIGNED (guint16
);
483 ASSIGN_UNSIGNED (guint8
);
485 ASSIGN_UNSIGNED (guint16
);
487 ASSIGN_UNSIGNED (guint32
);
489 ASSIGN_UNSIGNED (guint64
);
491 ASSIGN_SIGNED (gint8
);
493 ASSIGN_SIGNED (gint16
);
495 ASSIGN_SIGNED (gint32
);
497 ASSIGN_SIGNED (gint64
);
499 ASSIGN_REAL (gfloat
);
501 ASSIGN_REAL (gdouble
);
505 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
509 #undef NO_WIDENING_CONVERSION
510 #undef CHECK_WIDENING_CONVERSION
511 #undef ASSIGN_UNSIGNED
517 ves_icall_System_Array_SetValue (MonoArray
*this, MonoObject
*value
,
525 MONO_CHECK_ARG_NULL (idxs
);
527 ic
= idxs
->obj
.vtable
->klass
;
528 ac
= this->obj
.vtable
->klass
;
530 g_assert (ic
->rank
== 1);
531 if (idxs
->bounds
!= NULL
|| idxs
->max_length
!= ac
->rank
)
532 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
534 ind
= (gint32
*)idxs
->vector
;
536 if (this->bounds
== NULL
) {
537 if (*ind
< 0 || *ind
>= this->max_length
)
538 mono_raise_exception (mono_get_exception_index_out_of_range ());
540 ves_icall_System_Array_SetValueImpl (this, value
, *ind
);
544 for (i
= 0; i
< ac
->rank
; i
++)
545 if ((ind
[i
] < this->bounds
[i
].lower_bound
) ||
546 (ind
[i
] >= (mono_array_lower_bound_t
)this->bounds
[i
].length
+ this->bounds
[i
].lower_bound
))
547 mono_raise_exception (mono_get_exception_index_out_of_range ());
549 pos
= ind
[0] - this->bounds
[0].lower_bound
;
550 for (i
= 1; i
< ac
->rank
; i
++)
551 pos
= pos
* this->bounds
[i
].length
+ ind
[i
] -
552 this->bounds
[i
].lower_bound
;
554 ves_icall_System_Array_SetValueImpl (this, value
, pos
);
558 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
563 gboolean bounded
= FALSE
;
567 MONO_CHECK_ARG_NULL (type
);
568 MONO_CHECK_ARG_NULL (lengths
);
570 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
572 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
574 for (i
= 0; i
< mono_array_length (lengths
); i
++)
575 if (mono_array_get (lengths
, gint32
, i
) < 0)
576 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
578 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint32
, 0) != 0))
579 /* vectors are not the same as one dimensional arrays with no-zero bounds */
584 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
586 sizes
= alloca (aklass
->rank
* sizeof(intptr_t) * 2);
587 for (i
= 0; i
< aklass
->rank
; ++i
) {
588 sizes
[i
] = mono_array_get (lengths
, guint32
, i
);
590 sizes
[i
+ aklass
->rank
] = mono_array_get (bounds
, guint32
, i
);
592 sizes
[i
+ aklass
->rank
] = 0;
595 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, (intptr_t*)sizes
+ aklass
->rank
);
601 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
606 gboolean bounded
= FALSE
;
610 MONO_CHECK_ARG_NULL (type
);
611 MONO_CHECK_ARG_NULL (lengths
);
613 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
615 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
617 for (i
= 0; i
< mono_array_length (lengths
); i
++)
618 if ((mono_array_get (lengths
, gint64
, i
) < 0) ||
619 (mono_array_get (lengths
, gint64
, i
) > MONO_ARRAY_MAX_INDEX
))
620 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
622 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint64
, 0) != 0))
623 /* vectors are not the same as one dimensional arrays with no-zero bounds */
628 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
630 sizes
= alloca (aklass
->rank
* sizeof(intptr_t) * 2);
631 for (i
= 0; i
< aklass
->rank
; ++i
) {
632 sizes
[i
] = mono_array_get (lengths
, guint64
, i
);
634 sizes
[i
+ aklass
->rank
] = (mono_array_size_t
) mono_array_get (bounds
, guint64
, i
);
636 sizes
[i
+ aklass
->rank
] = 0;
639 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, (intptr_t*)sizes
+ aklass
->rank
);
645 ves_icall_System_Array_GetRank (MonoObject
*this)
649 return this->vtable
->klass
->rank
;
653 ves_icall_System_Array_GetLength (MonoArray
*this, gint32 dimension
)
655 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
660 if ((dimension
< 0) || (dimension
>= rank
))
661 mono_raise_exception (mono_get_exception_index_out_of_range ());
663 if (this->bounds
== NULL
)
664 length
= this->max_length
;
666 length
= this->bounds
[dimension
].length
;
668 #ifdef MONO_BIG_ARRAYS
669 if (length
> G_MAXINT32
)
670 mono_raise_exception (mono_get_exception_overflow ());
676 ves_icall_System_Array_GetLongLength (MonoArray
*this, gint32 dimension
)
678 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
682 if ((dimension
< 0) || (dimension
>= rank
))
683 mono_raise_exception (mono_get_exception_index_out_of_range ());
685 if (this->bounds
== NULL
)
686 return this->max_length
;
688 return this->bounds
[dimension
].length
;
692 ves_icall_System_Array_GetLowerBound (MonoArray
*this, gint32 dimension
)
694 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
698 if ((dimension
< 0) || (dimension
>= rank
))
699 mono_raise_exception (mono_get_exception_index_out_of_range ());
701 if (this->bounds
== NULL
)
704 return this->bounds
[dimension
].lower_bound
;
708 ves_icall_System_Array_ClearInternal (MonoArray
*arr
, int idx
, int length
)
710 int sz
= mono_array_element_size (mono_object_class (arr
));
711 memset (mono_array_addr_with_size (arr
, sz
, idx
), 0, length
* sz
);
715 ves_icall_System_Array_FastCopy (MonoArray
*source
, int source_idx
, MonoArray
* dest
, int dest_idx
, int length
)
720 MonoClass
*src_class
;
721 MonoClass
*dest_class
;
726 if (source
->obj
.vtable
->klass
->rank
!= dest
->obj
.vtable
->klass
->rank
)
729 if (source
->bounds
|| dest
->bounds
)
732 /* there's no integer overflow since mono_array_length returns an unsigned integer */
733 if ((dest_idx
+ length
> mono_array_length (dest
)) ||
734 (source_idx
+ length
> mono_array_length (source
)))
737 src_class
= source
->obj
.vtable
->klass
->element_class
;
738 dest_class
= dest
->obj
.vtable
->klass
->element_class
;
741 * Handle common cases.
744 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
745 if (src_class
== mono_defaults
.object_class
&& dest_class
->valuetype
) {
746 int has_refs
= dest_class
->has_references
;
747 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
748 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
749 if (elem
&& !mono_object_isinst (elem
, dest_class
))
753 element_size
= mono_array_element_size (dest
->obj
.vtable
->klass
);
754 memset (mono_array_addr_with_size (dest
, element_size
, dest_idx
), 0, element_size
* length
);
755 for (i
= 0; i
< length
; ++i
) {
756 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, source_idx
+ i
);
757 void *addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
+ i
);
761 mono_value_copy (addr
, (char *)elem
+ sizeof (MonoObject
), dest_class
);
763 memcpy (addr
, (char *)elem
+ sizeof (MonoObject
), element_size
);
768 /* Check if we're copying a char[] <==> (u)short[] */
769 if (src_class
!= dest_class
) {
770 if (dest_class
->valuetype
|| dest_class
->enumtype
|| src_class
->valuetype
|| src_class
->enumtype
)
773 if (mono_class_is_subclass_of (src_class
, dest_class
, FALSE
))
775 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
776 else if (mono_class_is_subclass_of (dest_class
, src_class
, FALSE
))
777 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
778 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
779 if (elem
&& !mono_object_isinst (elem
, dest_class
))
786 if (dest_class
->valuetype
) {
787 element_size
= mono_array_element_size (source
->obj
.vtable
->klass
);
788 source_addr
= mono_array_addr_with_size (source
, element_size
, source_idx
);
789 if (dest_class
->has_references
) {
790 mono_value_copy_array (dest
, dest_idx
, source_addr
, length
);
792 dest_addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
);
793 memmove (dest_addr
, source_addr
, element_size
* length
);
796 mono_array_memcpy_refs (dest
, dest_idx
, source
, source_idx
, length
);
803 ves_icall_System_Array_GetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
812 ao
= (MonoArray
*)this;
813 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
815 esize
= mono_array_element_size (ac
);
816 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
818 memcpy (value
, ea
, esize
);
822 ves_icall_System_Array_SetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
831 ao
= (MonoArray
*)this;
832 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
833 ec
= ac
->element_class
;
835 esize
= mono_array_element_size (ac
);
836 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
838 if (MONO_TYPE_IS_REFERENCE (&ec
->byval_arg
)) {
839 g_assert (esize
== sizeof (gpointer
));
840 mono_gc_wbarrier_generic_store (ea
, *(gpointer
*)value
);
842 g_assert (ec
->inited
);
843 g_assert (esize
== mono_class_value_size (ec
, NULL
));
844 if (ec
->has_references
)
845 mono_gc_wbarrier_value_copy (ea
, value
, 1, ec
);
847 memcpy (ea
, value
, esize
);
852 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray
*array
, MonoClassField
*field_handle
)
854 MonoClass
*klass
= array
->obj
.vtable
->klass
;
855 guint32 size
= mono_array_element_size (klass
);
856 MonoType
*type
= mono_type_get_underlying_type (&klass
->element_class
->byval_arg
);
858 const char *field_data
;
860 if (MONO_TYPE_IS_REFERENCE (type
) ||
861 (type
->type
== MONO_TYPE_VALUETYPE
&&
862 (!mono_type_get_class (type
) ||
863 mono_type_get_class (type
)->has_references
))) {
864 MonoException
*exc
= mono_get_exception_argument("array",
865 "Cannot initialize array containing references");
866 mono_raise_exception (exc
);
869 if (!(field_handle
->type
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) {
870 MonoException
*exc
= mono_get_exception_argument("field_handle",
871 "Field doesn't have an RVA");
872 mono_raise_exception (exc
);
875 size
*= array
->max_length
;
876 field_data
= mono_field_get_data (field_handle
);
878 if (size
> mono_type_size (field_handle
->type
, &align
)) {
879 MonoException
*exc
= mono_get_exception_argument("field_handle",
880 "Field not large enough to fill array");
881 mono_raise_exception (exc
);
884 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
886 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
887 guint ## n *src = (guint ## n *) field_data; \
888 guint ## n *end = (guint ## n *)((char*)src + size); \
890 for (; src < end; data++, src++) { \
891 *data = read ## n (src); \
895 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
897 switch (type
->type
) {
914 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
918 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
920 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_R8
) {
923 double *data
= (double*)mono_array_addr (array
, double, 0);
925 for (i
= 0; i
< size
; i
++, data
++) {
935 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
939 return offsetof (MonoString
, chars
);
943 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject
*obj
)
947 if ((obj
== NULL
) || (! (obj
->vtable
->klass
->valuetype
)))
950 return mono_object_clone (obj
);
954 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType
*handle
)
959 MONO_CHECK_ARG_NULL (handle
);
961 klass
= mono_class_from_mono_type (handle
);
962 MONO_CHECK_ARG (handle
, klass
);
964 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, TRUE
);
966 /* This will call the type constructor */
967 mono_runtime_class_init (vtable
);
971 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage
*image
)
975 mono_image_check_for_module_cctor (image
);
976 if (image
->has_module_cctor
) {
977 MonoClass
*module_klass
= mono_class_get (image
, MONO_TOKEN_TYPE_DEF
| 1);
978 /*It's fine to raise the exception here*/
979 mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass
, TRUE
));
984 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
989 /* later make this configurable and per-arch */
990 int min_size
= 4096 * 4 * sizeof (void*);
991 mono_thread_get_stack_bounds (&stack_addr
, &stack_size
);
992 /* if we have no info we are optimistic and assume there is enough room */
995 current
= (guint8
*)&stack_addr
;
996 if (current
> stack_addr
) {
997 if ((current
- stack_addr
) < min_size
)
1000 if (current
- (stack_addr
- stack_size
) < min_size
)
1007 ves_icall_System_Object_MemberwiseClone (MonoObject
*this)
1009 MONO_ARCH_SAVE_REGS
;
1011 return mono_object_clone (this);
1015 ves_icall_System_ValueType_InternalGetHashCode (MonoObject
*this, MonoArray
**fields
)
1018 MonoObject
**values
= NULL
;
1022 MonoClassField
* field
;
1025 MONO_ARCH_SAVE_REGS
;
1027 klass
= mono_object_class (this);
1029 if (mono_class_num_fields (klass
) == 0)
1030 return mono_object_hash (this);
1033 * Compute the starting value of the hashcode for fields of primitive
1034 * types, and return the remaining fields in an array to the managed side.
1035 * This way, we can avoid costly reflection operations in managed code.
1038 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1039 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1041 if (mono_field_is_deleted (field
))
1043 /* FIXME: Add more types */
1044 switch (field
->type
->type
) {
1046 result
^= *(gint32
*)((guint8
*)this + field
->offset
);
1048 case MONO_TYPE_STRING
: {
1050 s
= *(MonoString
**)((guint8
*)this + field
->offset
);
1052 result
^= mono_string_hash (s
);
1057 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
));
1058 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1059 values
[count
++] = o
;
1065 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
));
1066 for (i
= 0; i
< count
; ++i
)
1067 mono_array_setref (*fields
, i
, values
[i
]);
1075 ves_icall_System_ValueType_Equals (MonoObject
*this, MonoObject
*that
, MonoArray
**fields
)
1078 MonoObject
**values
= NULL
;
1080 MonoClassField
* field
;
1084 MONO_ARCH_SAVE_REGS
;
1086 MONO_CHECK_ARG_NULL (that
);
1088 if (this->vtable
!= that
->vtable
)
1091 klass
= mono_object_class (this);
1093 if (klass
->enumtype
&& mono_class_enum_basetype (klass
) && mono_class_enum_basetype (klass
)->type
== MONO_TYPE_I4
)
1094 return (*(gint32
*)((guint8
*)this + sizeof (MonoObject
)) == *(gint32
*)((guint8
*)that
+ sizeof (MonoObject
)));
1097 * Do the comparison for fields of primitive type and return a result if
1098 * possible. Otherwise, return the remaining fields in an array to the
1099 * managed side. This way, we can avoid costly reflection operations in
1104 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1105 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1107 if (mono_field_is_deleted (field
))
1109 /* FIXME: Add more types */
1110 switch (field
->type
->type
) {
1113 case MONO_TYPE_BOOLEAN
:
1114 if (*((guint8
*)this + field
->offset
) != *((guint8
*)that
+ field
->offset
))
1119 case MONO_TYPE_CHAR
:
1120 if (*(gint16
*)((guint8
*)this + field
->offset
) != *(gint16
*)((guint8
*)that
+ field
->offset
))
1125 if (*(gint32
*)((guint8
*)this + field
->offset
) != *(gint32
*)((guint8
*)that
+ field
->offset
))
1130 if (*(gint64
*)((guint8
*)this + field
->offset
) != *(gint64
*)((guint8
*)that
+ field
->offset
))
1134 if (*(float*)((guint8
*)this + field
->offset
) != *(float*)((guint8
*)that
+ field
->offset
))
1138 if (*(double*)((guint8
*)this + field
->offset
) != *(double*)((guint8
*)that
+ field
->offset
))
1143 case MONO_TYPE_STRING
: {
1144 MonoString
*s1
, *s2
;
1145 guint32 s1len
, s2len
;
1146 s1
= *(MonoString
**)((guint8
*)this + field
->offset
);
1147 s2
= *(MonoString
**)((guint8
*)that
+ field
->offset
);
1150 if ((s1
== NULL
) || (s2
== NULL
))
1152 s1len
= mono_string_length (s1
);
1153 s2len
= mono_string_length (s2
);
1157 if (memcmp (mono_string_chars (s1
), mono_string_chars (s2
), s1len
* sizeof (gunichar2
)) != 0)
1163 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
) * 2);
1164 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1165 values
[count
++] = o
;
1166 o
= mono_field_get_value_object (mono_object_domain (this), field
, that
);
1167 values
[count
++] = o
;
1170 if (klass
->enumtype
)
1171 /* enums only have one non-static field */
1177 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
));
1178 for (i
= 0; i
< count
; ++i
)
1179 mono_array_setref (*fields
, i
, values
[i
]);
1186 static MonoReflectionType
*
1187 ves_icall_System_Object_GetType (MonoObject
*obj
)
1189 MONO_ARCH_SAVE_REGS
;
1191 if (obj
->vtable
->klass
!= mono_defaults
.transparent_proxy_class
)
1192 return mono_type_get_object (mono_object_domain (obj
), &obj
->vtable
->klass
->byval_arg
);
1194 return mono_type_get_object (mono_object_domain (obj
), &((MonoTransparentProxy
*)obj
)->remote_class
->proxy_class
->byval_arg
);
1198 mono_type_type_from_obj (MonoReflectionType
*mtype
, MonoObject
*obj
)
1200 MONO_ARCH_SAVE_REGS
;
1202 mtype
->type
= &obj
->vtable
->klass
->byval_arg
;
1203 g_assert (mtype
->type
->type
);
1207 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
)
1209 MONO_ARCH_SAVE_REGS
;
1211 MONO_CHECK_ARG_NULL (obj
);
1213 return mono_image_create_token (mb
->dynamic_image
, obj
, TRUE
, TRUE
);
1217 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder
*mb
,
1218 MonoReflectionMethod
*method
,
1219 MonoArray
*opt_param_types
)
1221 MONO_ARCH_SAVE_REGS
;
1223 MONO_CHECK_ARG_NULL (method
);
1225 return mono_image_create_method_token (
1226 mb
->dynamic_image
, (MonoObject
*) method
, opt_param_types
);
1230 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
1232 MONO_ARCH_SAVE_REGS
;
1234 mono_image_create_pefile (mb
, file
);
1238 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
1240 MONO_ARCH_SAVE_REGS
;
1242 mono_image_build_metadata (mb
);
1246 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, guint32 token
)
1248 MONO_ARCH_SAVE_REGS
;
1250 mono_image_register_token (mb
->dynamic_image
, token
, obj
);
1254 get_caller (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1256 MonoMethod
**dest
= data
;
1258 /* skip unmanaged frames */
1274 get_executing (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1276 MonoMethod
**dest
= data
;
1278 /* skip unmanaged frames */
1283 if (!strcmp (m
->klass
->name_space
, "System.Reflection"))
1292 get_caller_no_reflection (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1294 MonoMethod
**dest
= data
;
1296 /* skip unmanaged frames */
1300 if (m
->wrapper_type
!= MONO_WRAPPER_NONE
)
1303 if (m
->klass
->image
== mono_defaults
.corlib
&& !strcmp (m
->klass
->name_space
, "System.Reflection"))
1317 static MonoReflectionType
*
1318 type_from_name (const char *str
, MonoBoolean ignoreCase
)
1320 MonoType
*type
= NULL
;
1321 MonoAssembly
*assembly
= NULL
;
1322 MonoTypeNameParse info
;
1323 char *temp_str
= g_strdup (str
);
1324 gboolean type_resolve
= FALSE
;
1326 MONO_ARCH_SAVE_REGS
;
1328 /* mono_reflection_parse_type() mangles the string */
1329 if (!mono_reflection_parse_type (temp_str
, &info
)) {
1330 mono_reflection_free_type_info (&info
);
1335 if (info
.assembly
.name
) {
1336 assembly
= mono_assembly_load (&info
.assembly
, NULL
, NULL
);
1338 MonoMethod
*m
= mono_method_get_last_managed ();
1339 MonoMethod
*dest
= m
;
1341 mono_stack_walk_no_il (get_caller_no_reflection
, &dest
);
1346 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1347 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1348 * to crash. This only seems to happen in some strange remoting
1349 * scenarios and I was unable to figure out what's happening there.
1350 * Dec 10, 2005 - Martin.
1354 assembly
= dest
->klass
->image
->assembly
;
1355 type_resolve
= TRUE
;
1357 g_warning (G_STRLOC
);
1362 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1363 type
= mono_reflection_get_type (assembly
->image
, &info
, ignoreCase
, &type_resolve
);
1366 if (!info
.assembly
.name
&& !type
) /* try mscorlib */
1367 type
= mono_reflection_get_type (NULL
, &info
, ignoreCase
, &type_resolve
);
1369 if (assembly
&& !type
&& type_resolve
) {
1370 type_resolve
= FALSE
; /* This will invoke TypeResolve if not done in the first 'if' */
1371 type
= mono_reflection_get_type (assembly
->image
, &info
, ignoreCase
, &type_resolve
);
1374 mono_reflection_free_type_info (&info
);
1380 return mono_type_get_object (mono_domain_get (), type
);
1384 MonoReflectionType
*
1385 mono_type_get (const char *str
)
1387 char *copy
= g_strdup (str
);
1388 MonoReflectionType
*type
= type_from_name (copy
, FALSE
);
1395 static MonoReflectionType
*
1396 ves_icall_type_from_name (MonoString
*name
,
1397 MonoBoolean throwOnError
,
1398 MonoBoolean ignoreCase
)
1400 char *str
= mono_string_to_utf8 (name
);
1401 MonoReflectionType
*type
;
1403 type
= type_from_name (str
, ignoreCase
);
1406 MonoException
*e
= NULL
;
1409 e
= mono_get_exception_type_load (name
, NULL
);
1411 mono_loader_clear_error ();
1413 mono_raise_exception (e
);
1420 static MonoReflectionType
*
1421 ves_icall_type_from_handle (MonoType
*handle
)
1423 MonoDomain
*domain
= mono_domain_get ();
1424 MonoClass
*klass
= mono_class_from_mono_type (handle
);
1426 MONO_ARCH_SAVE_REGS
;
1428 mono_class_init (klass
);
1429 return mono_type_get_object (domain
, handle
);
1433 ves_icall_System_Type_EqualsInternal (MonoReflectionType
*type
, MonoReflectionType
*c
)
1435 MONO_ARCH_SAVE_REGS
;
1437 if (c
&& type
->type
&& c
->type
)
1438 return mono_metadata_type_equal (type
->type
, c
->type
);
1440 return (type
== c
) ? TRUE
: FALSE
;
1443 /* System.TypeCode */
1462 TYPECODE_STRING
= 18
1466 ves_icall_type_GetTypeCodeInternal (MonoReflectionType
*type
)
1468 int t
= type
->type
->type
;
1470 MONO_ARCH_SAVE_REGS
;
1472 if (type
->type
->byref
)
1473 return TYPECODE_OBJECT
;
1477 case MONO_TYPE_VOID
:
1478 return TYPECODE_OBJECT
;
1479 case MONO_TYPE_BOOLEAN
:
1480 return TYPECODE_BOOLEAN
;
1482 return TYPECODE_BYTE
;
1484 return TYPECODE_SBYTE
;
1486 return TYPECODE_UINT16
;
1488 return TYPECODE_INT16
;
1489 case MONO_TYPE_CHAR
:
1490 return TYPECODE_CHAR
;
1494 return TYPECODE_OBJECT
;
1496 return TYPECODE_UINT32
;
1498 return TYPECODE_INT32
;
1500 return TYPECODE_UINT64
;
1502 return TYPECODE_INT64
;
1504 return TYPECODE_SINGLE
;
1506 return TYPECODE_DOUBLE
;
1507 case MONO_TYPE_VALUETYPE
:
1508 if (type
->type
->data
.klass
->enumtype
) {
1509 t
= mono_class_enum_basetype (type
->type
->data
.klass
)->type
;
1512 MonoClass
*k
= type
->type
->data
.klass
;
1513 if (strcmp (k
->name_space
, "System") == 0) {
1514 if (strcmp (k
->name
, "Decimal") == 0)
1515 return TYPECODE_DECIMAL
;
1516 else if (strcmp (k
->name
, "DateTime") == 0)
1517 return TYPECODE_DATETIME
;
1520 return TYPECODE_OBJECT
;
1521 case MONO_TYPE_STRING
:
1522 return TYPECODE_STRING
;
1523 case MONO_TYPE_SZARRAY
:
1524 case MONO_TYPE_ARRAY
:
1525 case MONO_TYPE_OBJECT
:
1527 case MONO_TYPE_MVAR
:
1528 case MONO_TYPE_TYPEDBYREF
:
1529 return TYPECODE_OBJECT
;
1530 case MONO_TYPE_CLASS
:
1532 MonoClass
*k
= type
->type
->data
.klass
;
1533 if (strcmp (k
->name_space
, "System") == 0) {
1534 if (strcmp (k
->name
, "DBNull") == 0)
1535 return TYPECODE_DBNULL
;
1538 return TYPECODE_OBJECT
;
1539 case MONO_TYPE_GENERICINST
:
1540 return TYPECODE_OBJECT
;
1542 g_error ("type 0x%02x not handled in GetTypeCode()", t
);
1548 ves_icall_type_is_subtype_of (MonoReflectionType
*type
, MonoReflectionType
*c
, MonoBoolean check_interfaces
)
1554 MONO_ARCH_SAVE_REGS
;
1556 g_assert (type
!= NULL
);
1558 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1560 if (!c
) /* FIXME: dont know what do do here */
1563 klass
= mono_class_from_mono_type (type
->type
);
1564 klassc
= mono_class_from_mono_type (c
->type
);
1566 if (type
->type
->byref
)
1567 return klassc
== mono_defaults
.object_class
;
1569 return mono_class_is_subclass_of (klass
, klassc
, check_interfaces
);
1573 ves_icall_type_is_assignable_from (MonoReflectionType
*type
, MonoReflectionType
*c
)
1579 MONO_ARCH_SAVE_REGS
;
1581 g_assert (type
!= NULL
);
1583 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1585 klass
= mono_class_from_mono_type (type
->type
);
1586 klassc
= mono_class_from_mono_type (c
->type
);
1588 if (type
->type
->byref
&& !c
->type
->byref
)
1591 return mono_class_is_assignable_from (klass
, klassc
);
1595 ves_icall_type_IsInstanceOfType (MonoReflectionType
*type
, MonoObject
*obj
)
1597 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1598 return mono_object_isinst (obj
, klass
) != NULL
;
1602 ves_icall_get_attributes (MonoReflectionType
*type
)
1604 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1606 MONO_ARCH_SAVE_REGS
;
1608 return klass
->flags
;
1611 static MonoReflectionMarshal
*
1612 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField
*field
)
1614 MonoClass
*klass
= field
->field
->parent
;
1615 MonoMarshalType
*info
;
1618 if (klass
->generic_container
||
1619 (klass
->generic_class
&& klass
->generic_class
->context
.class_inst
->is_open
))
1622 info
= mono_marshal_load_type_info (klass
);
1624 for (i
= 0; i
< info
->num_fields
; ++i
) {
1625 if (info
->fields
[i
].field
== field
->field
) {
1626 if (!info
->fields
[i
].mspec
)
1629 return mono_reflection_marshal_from_marshal_spec (field
->object
.vtable
->domain
, klass
, info
->fields
[i
].mspec
);
1636 static MonoReflectionField
*
1637 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
*handle
, MonoType
*type
)
1639 gboolean found
= FALSE
;
1646 klass
= handle
->parent
;
1648 klass
= mono_class_from_mono_type (type
);
1650 /* Check that the field belongs to the class */
1651 for (k
= klass
; k
; k
= k
->parent
) {
1652 if (k
== handle
->parent
) {
1659 /* The managed code will throw the exception */
1663 return mono_field_get_object (mono_domain_get (), klass
, handle
);
1667 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField
*field
, MonoBoolean optional
)
1669 MonoType
*type
= field
->field
->type
;
1671 return type_array_from_modifiers (field
->field
->parent
->image
, type
, optional
);
1675 ves_icall_get_method_info (MonoMethod
*method
, MonoMethodInfo
*info
)
1677 MonoDomain
*domain
= mono_domain_get ();
1678 MonoMethodSignature
* sig
;
1679 MONO_ARCH_SAVE_REGS
;
1681 sig
= mono_method_signature (method
);
1683 g_assert (mono_loader_get_last_error ());
1684 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1687 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &method
->klass
->byval_arg
));
1688 MONO_STRUCT_SETREF (info
, ret
, mono_type_get_object (domain
, sig
->ret
));
1689 info
->attrs
= method
->flags
;
1690 info
->implattrs
= method
->iflags
;
1691 if (sig
->call_convention
== MONO_CALL_DEFAULT
)
1692 info
->callconv
= sig
->sentinelpos
>= 0 ? 2 : 1;
1694 if (sig
->call_convention
== MONO_CALL_VARARG
|| sig
->sentinelpos
>= 0)
1699 info
->callconv
|= (sig
->hasthis
<< 5) | (sig
->explicit_this
<< 6);
1703 ves_icall_get_parameter_info (MonoMethod
*method
, MonoReflectionMethod
*member
)
1705 MonoDomain
*domain
= mono_domain_get ();
1707 return mono_param_get_objects_internal (domain
, method
, member
->reftype
? mono_class_from_mono_type (member
->reftype
->type
) : NULL
);
1710 static MonoReflectionMarshal
*
1711 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod
*method
)
1713 MonoDomain
*domain
= mono_domain_get ();
1714 MonoReflectionMarshal
* res
= NULL
;
1715 MonoMarshalSpec
**mspecs
;
1718 mspecs
= g_new (MonoMarshalSpec
*, mono_method_signature (method
)->param_count
+ 1);
1719 mono_method_get_marshal_info (method
, mspecs
);
1722 res
= mono_reflection_marshal_from_marshal_spec (domain
, method
->klass
, mspecs
[0]);
1724 for (i
= mono_method_signature (method
)->param_count
; i
>= 0; i
--)
1726 mono_metadata_free_marshal_spec (mspecs
[i
]);
1733 ves_icall_MonoField_GetFieldOffset (MonoReflectionField
*field
)
1735 return field
->field
->offset
- sizeof (MonoObject
);
1738 static MonoReflectionType
*
1739 ves_icall_MonoField_GetParentType (MonoReflectionField
*field
, MonoBoolean declaring
)
1742 MONO_ARCH_SAVE_REGS
;
1744 parent
= declaring
? field
->field
->parent
: field
->klass
;
1746 return mono_type_get_object (mono_object_domain (field
), &parent
->byval_arg
);
1750 ves_icall_MonoField_GetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
)
1752 MonoClass
*fklass
= field
->klass
;
1753 MonoClassField
*cf
= field
->field
;
1754 MonoDomain
*domain
= mono_object_domain (field
);
1756 if (fklass
->image
->assembly
->ref_only
)
1757 mono_raise_exception (mono_get_exception_invalid_operation (
1758 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1760 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
1761 mono_security_core_clr_ensure_reflection_access_field (cf
);
1763 return mono_field_get_value_object (domain
, cf
, obj
);
1767 ves_icall_MonoField_SetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
, MonoObject
*value
)
1769 MonoClassField
*cf
= field
->field
;
1772 MONO_ARCH_SAVE_REGS
;
1774 if (field
->klass
->image
->assembly
->ref_only
)
1775 mono_raise_exception (mono_get_exception_invalid_operation (
1776 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1778 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
1779 mono_security_core_clr_ensure_reflection_access_field (cf
);
1781 v
= (gchar
*) value
;
1782 if (!cf
->type
->byref
) {
1783 switch (cf
->type
->type
) {
1786 case MONO_TYPE_BOOLEAN
:
1789 case MONO_TYPE_CHAR
:
1798 case MONO_TYPE_VALUETYPE
:
1800 v
+= sizeof (MonoObject
);
1802 case MONO_TYPE_STRING
:
1803 case MONO_TYPE_OBJECT
:
1804 case MONO_TYPE_CLASS
:
1805 case MONO_TYPE_ARRAY
:
1806 case MONO_TYPE_SZARRAY
:
1809 case MONO_TYPE_GENERICINST
: {
1810 MonoGenericClass
*gclass
= cf
->type
->data
.generic_class
;
1811 g_assert (!gclass
->context
.class_inst
->is_open
);
1813 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1814 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1815 MonoObject
*nullable
;
1818 * Convert the boxed vtype into a Nullable structure.
1819 * This is complicated by the fact that Nullables have
1820 * a variable structure.
1822 nullable
= mono_object_new (mono_domain_get (), nklass
);
1824 mono_nullable_init (mono_object_unbox (nullable
), value
, nklass
);
1826 v
= mono_object_unbox (nullable
);
1829 if (gclass
->container_class
->valuetype
&& (v
!= NULL
))
1830 v
+= sizeof (MonoObject
);
1834 g_error ("type 0x%x not handled in "
1835 "ves_icall_FieldInfo_SetValueInternal", cf
->type
->type
);
1840 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
1841 MonoVTable
*vtable
= mono_class_vtable_full (mono_object_domain (field
), cf
->parent
, TRUE
);
1842 if (!vtable
->initialized
)
1843 mono_runtime_class_init (vtable
);
1844 mono_field_static_set_value (vtable
, cf
, v
);
1846 mono_field_set_value (obj
, cf
, v
);
1851 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField
*this)
1853 MonoObject
*o
= NULL
;
1854 MonoClassField
*field
= this->field
;
1856 MonoDomain
*domain
= mono_object_domain (this);
1858 MonoTypeEnum def_type
;
1859 const char *def_value
;
1861 MONO_ARCH_SAVE_REGS
;
1863 mono_class_init (field
->parent
);
1865 if (!(field
->type
->attrs
& FIELD_ATTRIBUTE_HAS_DEFAULT
))
1866 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
1868 if (field
->parent
->image
->dynamic
) {
1870 g_assert_not_reached ();
1873 def_value
= mono_class_get_field_default_value (field
, &def_type
);
1875 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
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 (MonoReflectionMonoEvent
*event
, MonoEventInfo
*info
)
1966 MonoDomain
*domain
= mono_object_domain (event
);
1968 MONO_ARCH_SAVE_REGS
;
1970 MONO_STRUCT_SETREF (info
, reflected_type
, mono_type_get_object (domain
, &event
->klass
->byval_arg
));
1971 MONO_STRUCT_SETREF (info
, declaring_type
, mono_type_get_object (domain
, &event
->event
->parent
->byval_arg
));
1973 MONO_STRUCT_SETREF (info
, name
, mono_string_new (domain
, event
->event
->name
));
1974 info
->attrs
= event
->event
->attrs
;
1975 MONO_STRUCT_SETREF (info
, add_method
, event
->event
->add
? mono_method_get_object (domain
, event
->event
->add
, NULL
): NULL
);
1976 MONO_STRUCT_SETREF (info
, remove_method
, event
->event
->remove
? mono_method_get_object (domain
, event
->event
->remove
, NULL
): NULL
);
1977 MONO_STRUCT_SETREF (info
, raise_method
, event
->event
->raise
? mono_method_get_object (domain
, event
->event
->raise
, NULL
): NULL
);
1979 #ifndef MONO_SMALL_CONFIG
1980 if (event
->event
->other
) {
1982 while (event
->event
->other
[n
])
1984 MONO_STRUCT_SETREF (info
, other_methods
, mono_array_new (domain
, mono_defaults
.method_info_class
, n
));
1986 for (i
= 0; i
< n
; i
++)
1987 mono_array_setref (info
->other_methods
, i
, mono_method_get_object (domain
, event
->event
->other
[i
], NULL
));
1993 ves_icall_Type_GetInterfaces (MonoReflectionType
* type
)
1996 MonoDomain
*domain
= mono_object_domain (type
);
1998 GPtrArray
*ifaces
= NULL
;
2000 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2003 MonoGenericContext
*context
= NULL
;
2005 MONO_ARCH_SAVE_REGS
;
2007 if (class->generic_class
&& class->generic_class
->context
.class_inst
->is_open
) {
2008 context
= mono_class_get_context (class);
2009 class = class->generic_class
->container_class
;
2012 mono_class_setup_vtable (class);
2014 slots
= mono_bitset_new (class->max_interface_id
+ 1, 0);
2016 for (parent
= class; parent
; parent
= parent
->parent
) {
2017 GPtrArray
*tmp_ifaces
= mono_class_get_implemented_interfaces (parent
, &error
);
2018 if (!mono_error_ok (&error
)) {
2019 mono_bitset_free (slots
);
2020 mono_error_raise_exception (&error
);
2022 } else if (tmp_ifaces
) {
2023 for (i
= 0; i
< tmp_ifaces
->len
; ++i
) {
2024 MonoClass
*ic
= g_ptr_array_index (tmp_ifaces
, i
);
2026 if (mono_bitset_test (slots
, ic
->interface_id
))
2029 mono_bitset_set (slots
, ic
->interface_id
);
2031 ifaces
= g_ptr_array_new ();
2032 g_ptr_array_add (ifaces
, ic
);
2034 g_ptr_array_free (tmp_ifaces
, TRUE
);
2037 mono_bitset_free (slots
);
2040 return mono_array_new_cached (domain
, mono_defaults
.monotype_class
, 0);
2042 intf
= mono_array_new_cached (domain
, mono_defaults
.monotype_class
, ifaces
->len
);
2043 for (i
= 0; i
< ifaces
->len
; ++i
) {
2044 MonoClass
*ic
= g_ptr_array_index (ifaces
, i
);
2045 MonoType
*ret
= &ic
->byval_arg
, *inflated
= NULL
;
2046 if (context
&& ic
->generic_class
&& ic
->generic_class
->context
.class_inst
->is_open
)
2047 inflated
= ret
= mono_class_inflate_generic_type (ret
, context
);
2049 mono_array_setref (intf
, i
, mono_type_get_object (domain
, ret
));
2051 mono_metadata_free_type (inflated
);
2053 g_ptr_array_free (ifaces
, TRUE
);
2059 ves_icall_Type_GetInterfaceMapData (MonoReflectionType
*type
, MonoReflectionType
*iface
, MonoArray
**targets
, MonoArray
**methods
)
2061 gboolean variance_used
;
2062 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2063 MonoClass
*iclass
= mono_class_from_mono_type (iface
->type
);
2064 MonoReflectionMethod
*member
;
2067 int i
= 0, len
, ioffset
;
2070 MONO_ARCH_SAVE_REGS
;
2072 mono_class_setup_vtable (class);
2074 ioffset
= mono_class_interface_offset_with_variance (class, iclass
, &variance_used
);
2078 len
= mono_class_num_methods (iclass
);
2079 domain
= mono_object_domain (type
);
2080 mono_gc_wbarrier_generic_store (targets
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.method_info_class
, len
));
2081 mono_gc_wbarrier_generic_store (methods
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.method_info_class
, len
));
2083 while ((method
= mono_class_get_methods (iclass
, &iter
))) {
2084 member
= mono_method_get_object (domain
, method
, iclass
);
2085 mono_array_setref (*methods
, i
, member
);
2086 member
= mono_method_get_object (domain
, class->vtable
[i
+ ioffset
], class);
2087 mono_array_setref (*targets
, i
, member
);
2094 ves_icall_Type_GetPacking (MonoReflectionType
*type
, guint32
*packing
, guint32
*size
)
2096 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2098 if (klass
->image
->dynamic
) {
2099 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)type
;
2100 *packing
= tb
->packing_size
;
2101 *size
= tb
->class_size
;
2103 mono_metadata_packing_from_typedef (klass
->image
, klass
->type_token
, packing
, size
);
2107 static MonoReflectionType
*
2108 ves_icall_MonoType_GetElementType (MonoReflectionType
*type
)
2112 MONO_ARCH_SAVE_REGS
;
2114 if (!type
->type
->byref
&& type
->type
->type
== MONO_TYPE_SZARRAY
)
2115 return mono_type_get_object (mono_object_domain (type
), &type
->type
->data
.klass
->byval_arg
);
2117 class = mono_class_from_mono_type (type
->type
);
2119 // GetElementType should only return a type for:
2120 // Array Pointer PassedByRef
2121 if (type
->type
->byref
)
2122 return mono_type_get_object (mono_object_domain (type
), &class->byval_arg
);
2123 else if (class->element_class
&& MONO_CLASS_IS_ARRAY (class))
2124 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2125 else if (class->element_class
&& type
->type
->type
== MONO_TYPE_PTR
)
2126 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2131 static MonoReflectionType
*
2132 ves_icall_get_type_parent (MonoReflectionType
*type
)
2134 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2136 MONO_ARCH_SAVE_REGS
;
2138 return class->parent
? mono_type_get_object (mono_object_domain (type
), &class->parent
->byval_arg
): NULL
;
2142 ves_icall_type_ispointer (MonoReflectionType
*type
)
2144 MONO_ARCH_SAVE_REGS
;
2146 return type
->type
->type
== MONO_TYPE_PTR
;
2150 ves_icall_type_isprimitive (MonoReflectionType
*type
)
2152 MONO_ARCH_SAVE_REGS
;
2154 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
)));
2158 ves_icall_type_isbyref (MonoReflectionType
*type
)
2160 MONO_ARCH_SAVE_REGS
;
2162 return type
->type
->byref
;
2166 ves_icall_type_iscomobject (MonoReflectionType
*type
)
2168 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2169 MONO_ARCH_SAVE_REGS
;
2171 return (klass
&& klass
->is_com_object
);
2174 static MonoReflectionModule
*
2175 ves_icall_MonoType_get_Module (MonoReflectionType
*type
)
2177 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2179 MONO_ARCH_SAVE_REGS
;
2181 return mono_module_get_object (mono_object_domain (type
), class->image
);
2184 static MonoReflectionAssembly
*
2185 ves_icall_MonoType_get_Assembly (MonoReflectionType
*type
)
2187 MonoDomain
*domain
= mono_domain_get ();
2188 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2190 MONO_ARCH_SAVE_REGS
;
2192 return mono_assembly_get_object (domain
, class->image
->assembly
);
2195 static MonoReflectionType
*
2196 ves_icall_MonoType_get_DeclaringType (MonoReflectionType
*type
)
2198 MonoDomain
*domain
= mono_domain_get ();
2201 MONO_ARCH_SAVE_REGS
;
2203 if (type
->type
->byref
)
2205 if (type
->type
->type
== MONO_TYPE_VAR
)
2206 class = mono_type_get_generic_param_owner (type
->type
)->owner
.klass
;
2207 else if (type
->type
->type
== MONO_TYPE_MVAR
)
2208 class = mono_type_get_generic_param_owner (type
->type
)->owner
.method
->klass
;
2210 class = mono_class_from_mono_type (type
->type
)->nested_in
;
2212 return class ? mono_type_get_object (domain
, &class->byval_arg
) : NULL
;
2215 static MonoReflectionType
*
2216 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType
*type
)
2218 MonoDomain
*domain
= mono_domain_get ();
2219 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2221 MONO_ARCH_SAVE_REGS
;
2223 if (class->enumtype
&& mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
2224 return mono_type_get_object (domain
, mono_class_enum_basetype (class));
2225 else if (class->element_class
)
2226 return mono_type_get_object (domain
, &class->element_class
->byval_arg
);
2232 ves_icall_MonoType_get_Name (MonoReflectionType
*type
)
2234 MonoDomain
*domain
= mono_domain_get ();
2235 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2237 MONO_ARCH_SAVE_REGS
;
2239 if (type
->type
->byref
) {
2240 char *n
= g_strdup_printf ("%s&", class->name
);
2241 MonoString
*res
= mono_string_new (domain
, n
);
2247 return mono_string_new (domain
, class->name
);
2252 ves_icall_MonoType_get_Namespace (MonoReflectionType
*type
)
2254 MonoDomain
*domain
= mono_domain_get ();
2255 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2257 MONO_ARCH_SAVE_REGS
;
2259 while (class->nested_in
)
2260 class = class->nested_in
;
2262 if (class->name_space
[0] == '\0')
2265 return mono_string_new (domain
, class->name_space
);
2269 ves_icall_MonoType_GetArrayRank (MonoReflectionType
*type
)
2273 if (type
->type
->type
!= MONO_TYPE_ARRAY
&& type
->type
->type
!= MONO_TYPE_SZARRAY
)
2274 mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2276 class = mono_class_from_mono_type (type
->type
);
2281 ves_icall_MonoType_GetGenericArguments (MonoReflectionType
*type
)
2284 MonoClass
*klass
, *pklass
;
2285 MonoDomain
*domain
= mono_object_domain (type
);
2286 MonoVTable
*array_vtable
= mono_class_vtable_full (domain
, mono_array_class_get_cached (mono_defaults
.systemtype_class
, 1), TRUE
);
2288 MONO_ARCH_SAVE_REGS
;
2290 klass
= mono_class_from_mono_type (type
->type
);
2292 if (klass
->generic_container
) {
2293 MonoGenericContainer
*container
= klass
->generic_container
;
2294 res
= mono_array_new_specific (array_vtable
, container
->type_argc
);
2295 for (i
= 0; i
< container
->type_argc
; ++i
) {
2296 pklass
= mono_class_from_generic_parameter (mono_generic_container_get_param (container
, i
), klass
->image
, FALSE
);
2297 mono_array_setref (res
, i
, mono_type_get_object (domain
, &pklass
->byval_arg
));
2299 } else if (klass
->generic_class
) {
2300 MonoGenericInst
*inst
= klass
->generic_class
->context
.class_inst
;
2301 res
= mono_array_new_specific (array_vtable
, inst
->type_argc
);
2302 for (i
= 0; i
< inst
->type_argc
; ++i
)
2303 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2305 res
= mono_array_new_specific (array_vtable
, 0);
2311 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType
*type
)
2314 MONO_ARCH_SAVE_REGS
;
2316 if (!IS_MONOTYPE (type
))
2319 if (type
->type
->byref
)
2322 klass
= mono_class_from_mono_type (type
->type
);
2324 return klass
->generic_container
!= NULL
;
2327 static MonoReflectionType
*
2328 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType
*type
)
2331 MONO_ARCH_SAVE_REGS
;
2333 if (type
->type
->byref
)
2336 klass
= mono_class_from_mono_type (type
->type
);
2337 if (klass
->generic_container
) {
2338 return type
; /* check this one */
2340 if (klass
->generic_class
) {
2341 MonoClass
*generic_class
= klass
->generic_class
->container_class
;
2344 tb
= mono_class_get_ref_info (generic_class
);
2346 if (generic_class
->wastypebuilder
&& tb
)
2349 return mono_type_get_object (mono_object_domain (type
), &generic_class
->byval_arg
);
2354 static MonoReflectionType
*
2355 ves_icall_Type_MakeGenericType (MonoReflectionType
*type
, MonoArray
*type_array
)
2357 MonoType
*geninst
, **types
;
2360 MONO_ARCH_SAVE_REGS
;
2362 count
= mono_array_length (type_array
);
2363 types
= g_new0 (MonoType
*, count
);
2365 for (i
= 0; i
< count
; i
++) {
2366 MonoReflectionType
*t
= mono_array_get (type_array
, gpointer
, i
);
2367 types
[i
] = t
->type
;
2370 geninst
= mono_reflection_bind_generic_parameters (type
, count
, types
);
2375 return mono_type_get_object (mono_object_domain (type
), geninst
);
2379 ves_icall_Type_get_IsGenericInstance (MonoReflectionType
*type
)
2382 MONO_ARCH_SAVE_REGS
;
2384 if (type
->type
->byref
)
2387 klass
= mono_class_from_mono_type (type
->type
);
2388 return klass
->generic_class
!= NULL
;
2392 ves_icall_Type_get_IsGenericType (MonoReflectionType
*type
)
2395 MONO_ARCH_SAVE_REGS
;
2397 if (!IS_MONOTYPE (type
))
2400 if (type
->type
->byref
)
2403 klass
= mono_class_from_mono_type (type
->type
);
2404 return klass
->generic_class
!= NULL
|| klass
->generic_container
!= NULL
;
2408 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType
*type
)
2410 MONO_ARCH_SAVE_REGS
;
2412 if (!IS_MONOTYPE (type
))
2415 if (is_generic_parameter (type
->type
))
2416 return mono_type_get_generic_param_num (type
->type
);
2420 static GenericParameterAttributes
2421 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType
*type
)
2423 MONO_ARCH_SAVE_REGS
;
2425 g_assert (IS_MONOTYPE (type
));
2426 g_assert (is_generic_parameter (type
->type
));
2427 return mono_generic_param_info (type
->type
->data
.generic_param
)->flags
;
2431 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType
*type
)
2433 MonoGenericParamInfo
*param_info
;
2439 MONO_ARCH_SAVE_REGS
;
2441 g_assert (IS_MONOTYPE (type
));
2443 domain
= mono_object_domain (type
);
2444 param_info
= mono_generic_param_info (type
->type
->data
.generic_param
);
2445 for (count
= 0, ptr
= param_info
->constraints
; ptr
&& *ptr
; ptr
++, count
++)
2448 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
2449 for (i
= 0; i
< count
; i
++)
2450 mono_array_setref (res
, i
, mono_type_get_object (domain
, ¶m_info
->constraints
[i
]->byval_arg
));
2457 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType
*type
)
2459 MONO_ARCH_SAVE_REGS
;
2460 return is_generic_parameter (type
->type
);
2464 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder
*tb
)
2466 MONO_ARCH_SAVE_REGS
;
2467 return is_generic_parameter (tb
->type
.type
);
2471 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType
*enumtype
,
2472 MonoReflectionType
*t
)
2474 enumtype
->type
= t
->type
;
2477 static MonoReflectionMethod
*
2478 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType
*type
,
2479 MonoReflectionMethod
* generic
)
2486 MONO_ARCH_SAVE_REGS
;
2488 domain
= ((MonoObject
*)type
)->vtable
->domain
;
2490 klass
= mono_class_from_mono_type (type
->type
);
2493 while ((method
= mono_class_get_methods (klass
, &iter
))) {
2494 if (method
->token
== generic
->method
->token
)
2495 return mono_method_get_object (domain
, method
, klass
);
2503 static MonoReflectionMethod
*
2504 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType
*ref_type
)
2507 MonoType
*type
= ref_type
->type
;
2509 MONO_ARCH_SAVE_REGS
;
2511 if (type
->byref
|| (type
->type
!= MONO_TYPE_MVAR
&& type
->type
!= MONO_TYPE_VAR
))
2512 mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2513 if (type
->type
== MONO_TYPE_VAR
)
2516 method
= mono_type_get_generic_param_owner (type
)->owner
.method
;
2518 return mono_method_get_object (mono_object_domain (ref_type
), method
, method
->klass
);
2521 static MonoReflectionDllImportAttribute
*
2522 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod
*method
)
2524 static MonoClass
*DllImportAttributeClass
= NULL
;
2525 MonoDomain
*domain
= mono_domain_get ();
2526 MonoReflectionDllImportAttribute
*attr
;
2527 MonoImage
*image
= method
->klass
->image
;
2528 MonoMethodPInvoke
*piinfo
= (MonoMethodPInvoke
*)method
;
2529 MonoTableInfo
*tables
= image
->tables
;
2530 MonoTableInfo
*im
= &tables
[MONO_TABLE_IMPLMAP
];
2531 MonoTableInfo
*mr
= &tables
[MONO_TABLE_MODULEREF
];
2532 guint32 im_cols
[MONO_IMPLMAP_SIZE
];
2533 guint32 scope_token
;
2534 const char *import
= NULL
;
2535 const char *scope
= NULL
;
2538 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
2541 if (!DllImportAttributeClass
) {
2542 DllImportAttributeClass
=
2543 mono_class_from_name (mono_defaults
.corlib
,
2544 "System.Runtime.InteropServices", "DllImportAttribute");
2545 g_assert (DllImportAttributeClass
);
2548 if (method
->klass
->image
->dynamic
) {
2549 MonoReflectionMethodAux
*method_aux
=
2550 g_hash_table_lookup (
2551 ((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
2553 import
= method_aux
->dllentry
;
2554 scope
= method_aux
->dll
;
2557 if (!import
|| !scope
) {
2558 mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2563 if (piinfo
->implmap_idx
) {
2564 mono_metadata_decode_row (im
, piinfo
->implmap_idx
- 1, im_cols
, MONO_IMPLMAP_SIZE
);
2566 piinfo
->piflags
= im_cols
[MONO_IMPLMAP_FLAGS
];
2567 import
= mono_metadata_string_heap (image
, im_cols
[MONO_IMPLMAP_NAME
]);
2568 scope_token
= mono_metadata_decode_row_col (mr
, im_cols
[MONO_IMPLMAP_SCOPE
] - 1, MONO_MODULEREF_NAME
);
2569 scope
= mono_metadata_string_heap (image
, scope_token
);
2572 flags
= piinfo
->piflags
;
2574 attr
= (MonoReflectionDllImportAttribute
*)mono_object_new (domain
, DllImportAttributeClass
);
2576 MONO_OBJECT_SETREF (attr
, dll
, mono_string_new (domain
, scope
));
2577 MONO_OBJECT_SETREF (attr
, entry_point
, mono_string_new (domain
, import
));
2578 attr
->call_conv
= (flags
& 0x700) >> 8;
2579 attr
->charset
= ((flags
& 0x6) >> 1) + 1;
2580 if (attr
->charset
== 1)
2582 attr
->exact_spelling
= (flags
& 0x1) != 0;
2583 attr
->set_last_error
= (flags
& 0x40) != 0;
2584 attr
->best_fit_mapping
= (flags
& 0x30) == 0x10;
2585 attr
->throw_on_unmappable
= (flags
& 0x3000) == 0x1000;
2586 attr
->preserve_sig
= FALSE
;
2591 static MonoReflectionMethod
*
2592 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod
*method
)
2594 MonoMethodInflated
*imethod
;
2597 MONO_ARCH_SAVE_REGS
;
2599 if (method
->method
->is_generic
)
2602 if (!method
->method
->is_inflated
)
2605 imethod
= (MonoMethodInflated
*) method
->method
;
2607 result
= imethod
->declaring
;
2608 /* Not a generic method. */
2609 if (!result
->is_generic
)
2612 if (method
->method
->klass
->image
->dynamic
) {
2613 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->method
->klass
->image
;
2614 MonoReflectionMethod
*res
;
2617 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2618 * the dynamic case as well ?
2620 mono_loader_lock ();
2621 res
= mono_g_hash_table_lookup (image
->generic_def_objects
, imethod
);
2622 mono_loader_unlock ();
2628 if (imethod
->context
.class_inst
) {
2629 MonoClass
*klass
= ((MonoMethod
*) imethod
)->klass
;
2630 /*Generic methods gets the context of the GTD.*/
2631 if (mono_class_get_context (klass
))
2632 result
= mono_class_inflate_generic_method_full (result
, klass
, mono_class_get_context (klass
));
2635 return mono_method_get_object (mono_object_domain (method
), result
, NULL
);
2639 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod
*method
)
2641 MONO_ARCH_SAVE_REGS
;
2643 return mono_method_signature (method
->method
)->generic_param_count
!= 0;
2647 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod
*method
)
2649 MONO_ARCH_SAVE_REGS
;
2651 return method
->method
->is_generic
;
2655 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod
*method
)
2660 MONO_ARCH_SAVE_REGS
;
2662 domain
= mono_object_domain (method
);
2664 if (method
->method
->is_inflated
) {
2665 MonoGenericInst
*inst
= mono_method_get_context (method
->method
)->method_inst
;
2668 count
= inst
->type_argc
;
2669 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2671 for (i
= 0; i
< count
; i
++)
2672 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2678 count
= mono_method_signature (method
->method
)->generic_param_count
;
2679 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2681 for (i
= 0; i
< count
; i
++) {
2682 MonoGenericContainer
*container
= mono_method_get_generic_container (method
->method
);
2683 MonoGenericParam
*param
= mono_generic_container_get_param (container
, i
);
2684 MonoClass
*pklass
= mono_class_from_generic_parameter (
2685 param
, method
->method
->klass
->image
, TRUE
);
2686 mono_array_setref (res
, i
,
2687 mono_type_get_object (domain
, &pklass
->byval_arg
));
2694 ves_icall_InternalInvoke (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoException
**exc
)
2697 * Invoke from reflection is supposed to always be a virtual call (the API
2698 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2699 * greater flexibility.
2701 MonoMethod
*m
= method
->method
;
2705 MONO_ARCH_SAVE_REGS
;
2709 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
2710 mono_security_core_clr_ensure_reflection_access_method (m
);
2712 if (!(m
->flags
& METHOD_ATTRIBUTE_STATIC
)) {
2713 if (!mono_class_vtable_full (mono_object_domain (method
), m
->klass
, FALSE
)) {
2714 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_class_get_exception_for_failure (m
->klass
));
2719 if (!mono_object_isinst (this, m
->klass
)) {
2720 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Object does not match target type."));
2723 m
= mono_object_get_virtual_method (this, m
);
2724 /* must pass the pointer to the value for valuetype methods */
2725 if (m
->klass
->valuetype
)
2726 obj
= mono_object_unbox (this);
2727 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
2728 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target."));
2733 pcount
= params
? mono_array_length (params
): 0;
2734 if (pcount
!= mono_method_signature (m
)->param_count
) {
2735 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException"));
2739 if ((m
->klass
->flags
& TYPE_ATTRIBUTE_ABSTRACT
) && !strcmp (m
->name
, ".ctor") && !this) {
2740 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
2744 if (m
->klass
->image
->assembly
->ref_only
) {
2745 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2749 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
2752 intptr_t *lower_bounds
;
2753 pcount
= mono_array_length (params
);
2754 lengths
= alloca (sizeof (uintptr_t) * pcount
);
2755 /* Note: the synthetized array .ctors have int32 as argument type */
2756 for (i
= 0; i
< pcount
; ++i
)
2757 lengths
[i
] = *(int32_t*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
2759 if (m
->klass
->rank
== pcount
) {
2760 /* Only lengths provided. */
2761 lower_bounds
= NULL
;
2763 g_assert (pcount
== (m
->klass
->rank
* 2));
2764 /* lower bounds are first. */
2765 lower_bounds
= (intptr_t*)lengths
;
2766 lengths
+= m
->klass
->rank
;
2769 return (MonoObject
*)mono_array_new_full (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
);
2771 return mono_runtime_invoke_array (m
, obj
, params
, NULL
);
2775 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoArray
**outArgs
)
2777 MonoDomain
*domain
= mono_object_domain (method
);
2778 MonoMethod
*m
= method
->method
;
2779 MonoMethodSignature
*sig
= mono_method_signature (m
);
2780 MonoArray
*out_args
;
2782 int i
, j
, outarg_count
= 0;
2784 MONO_ARCH_SAVE_REGS
;
2786 if (m
->klass
== mono_defaults
.object_class
) {
2788 if (!strcmp (m
->name
, "FieldGetter")) {
2789 MonoClass
*k
= this->vtable
->klass
;
2793 /* If this is a proxy, then it must be a CBO */
2794 if (k
== mono_defaults
.transparent_proxy_class
) {
2795 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2796 this = tp
->rp
->unwrapped_server
;
2798 k
= this->vtable
->klass
;
2801 name
= mono_array_get (params
, MonoString
*, 1);
2802 str
= mono_string_to_utf8 (name
);
2805 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2807 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2808 if (field_klass
->valuetype
)
2809 result
= mono_value_box (domain
, field_klass
, (char *)this + field
->offset
);
2811 result
= *((gpointer
*)((char *)this + field
->offset
));
2813 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 1);
2814 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2815 mono_array_setref (out_args
, 0, result
);
2823 g_assert_not_reached ();
2825 } else if (!strcmp (m
->name
, "FieldSetter")) {
2826 MonoClass
*k
= this->vtable
->klass
;
2832 /* If this is a proxy, then it must be a CBO */
2833 if (k
== mono_defaults
.transparent_proxy_class
) {
2834 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2835 this = tp
->rp
->unwrapped_server
;
2837 k
= this->vtable
->klass
;
2840 name
= mono_array_get (params
, MonoString
*, 1);
2841 str
= mono_string_to_utf8 (name
);
2844 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2846 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2847 MonoObject
*val
= mono_array_get (params
, gpointer
, 2);
2849 if (field_klass
->valuetype
) {
2850 size
= mono_type_size (field
->type
, &align
);
2851 g_assert (size
== mono_class_value_size (field_klass
, NULL
));
2852 mono_gc_wbarrier_value_copy ((char *)this + field
->offset
, (char*)val
+ sizeof (MonoObject
), 1, field_klass
);
2854 mono_gc_wbarrier_set_field (this, (char*)this + field
->offset
, val
);
2857 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 0);
2858 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2868 g_assert_not_reached ();
2873 for (i
= 0; i
< mono_array_length (params
); i
++) {
2874 if (sig
->params
[i
]->byref
)
2878 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, outarg_count
);
2880 /* handle constructors only for objects already allocated */
2881 if (!strcmp (method
->method
->name
, ".ctor"))
2884 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2885 g_assert (!method
->method
->klass
->valuetype
);
2886 result
= mono_runtime_invoke_array (method
->method
, this, params
, NULL
);
2888 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
2889 if (sig
->params
[i
]->byref
) {
2891 arg
= mono_array_get (params
, gpointer
, i
);
2892 mono_array_setref (out_args
, j
, arg
);
2897 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2903 read_enum_value (char *mem
, int type
)
2907 return *(guint8
*)mem
;
2909 return *(gint8
*)mem
;
2911 return *(guint16
*)mem
;
2913 return *(gint16
*)mem
;
2915 return *(guint32
*)mem
;
2917 return *(gint32
*)mem
;
2919 return *(guint64
*)mem
;
2921 return *(gint64
*)mem
;
2923 g_assert_not_reached ();
2929 write_enum_value (char *mem
, int type
, guint64 value
)
2933 case MONO_TYPE_I1
: {
2934 guint8
*p
= (guint8
*)mem
;
2939 case MONO_TYPE_I2
: {
2940 guint16
*p
= (void*)mem
;
2945 case MONO_TYPE_I4
: {
2946 guint32
*p
= (void*)mem
;
2951 case MONO_TYPE_I8
: {
2952 guint64
*p
= (void*)mem
;
2957 g_assert_not_reached ();
2963 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, MonoObject
*value
)
2966 MonoClass
*enumc
, *objc
;
2971 MONO_ARCH_SAVE_REGS
;
2973 MONO_CHECK_ARG_NULL (enumType
);
2974 MONO_CHECK_ARG_NULL (value
);
2976 domain
= mono_object_domain (enumType
);
2977 enumc
= mono_class_from_mono_type (enumType
->type
);
2978 objc
= value
->vtable
->klass
;
2980 if (!enumc
->enumtype
)
2981 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2982 if (!((objc
->enumtype
) || (objc
->byval_arg
.type
>= MONO_TYPE_I1
&& objc
->byval_arg
.type
<= MONO_TYPE_U8
)))
2983 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."));
2985 etype
= mono_class_enum_basetype (enumc
);
2987 /* MS throws this for typebuilders */
2988 mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
2990 res
= mono_object_new (domain
, enumc
);
2991 val
= read_enum_value ((char *)value
+ sizeof (MonoObject
), objc
->enumtype
? mono_class_enum_basetype (objc
)->type
: objc
->byval_arg
.type
);
2992 write_enum_value ((char *)res
+ sizeof (MonoObject
), etype
->type
, val
);
2998 ves_icall_System_Enum_get_value (MonoObject
*this)
3006 MONO_ARCH_SAVE_REGS
;
3011 g_assert (this->vtable
->klass
->enumtype
);
3013 enumc
= mono_class_from_mono_type (mono_class_enum_basetype (this->vtable
->klass
));
3014 res
= mono_object_new (mono_object_domain (this), enumc
);
3015 dst
= (char *)res
+ sizeof (MonoObject
);
3016 src
= (char *)this + sizeof (MonoObject
);
3017 size
= mono_class_value_size (enumc
, NULL
);
3019 memcpy (dst
, src
, size
);
3024 static MonoReflectionType
*
3025 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3029 MONO_ARCH_SAVE_REGS
;
3031 etype
= mono_class_enum_basetype (mono_class_from_mono_type (type
->type
));
3033 /* MS throws this for typebuilders */
3034 mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
3036 return mono_type_get_object (mono_object_domain (type
), etype
);
3040 ves_icall_System_Enum_compare_value_to (MonoObject
*this, MonoObject
*other
)
3042 gpointer tdata
= (char *)this + sizeof (MonoObject
);
3043 gpointer odata
= (char *)other
+ sizeof (MonoObject
);
3044 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3045 g_assert (basetype
);
3047 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3048 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3049 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3052 return me > other ? 1 : -1; \
3055 #define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
3056 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3057 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3060 return me - other; \
3063 switch (basetype
->type
) {
3065 COMPARE_ENUM_VALUES (guint8
);
3067 COMPARE_ENUM_VALUES (gint8
);
3068 case MONO_TYPE_CHAR
:
3070 COMPARE_ENUM_VALUES_RANGE (guint16
);
3072 COMPARE_ENUM_VALUES (gint16
);
3074 COMPARE_ENUM_VALUES (guint32
);
3076 COMPARE_ENUM_VALUES (gint32
);
3078 COMPARE_ENUM_VALUES (guint64
);
3080 COMPARE_ENUM_VALUES (gint64
);
3082 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3084 #undef COMPARE_ENUM_VALUES_RANGE
3085 #undef COMPARE_ENUM_VALUES
3090 ves_icall_System_Enum_get_hashcode (MonoObject
*this)
3092 gpointer data
= (char *)this + sizeof (MonoObject
);
3093 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3094 g_assert (basetype
);
3096 switch (basetype
->type
) {
3098 return *((gint8
*)data
);
3100 return *((guint8
*)data
);
3101 case MONO_TYPE_CHAR
:
3103 return *((guint16
*)data
);
3106 return *((gint16
*)data
);
3108 return *((guint32
*)data
);
3110 return *((gint32
*)data
);
3112 case MONO_TYPE_I8
: {
3113 gint64 value
= *((gint64
*)data
);
3114 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3117 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3123 ves_icall_get_enum_info (MonoReflectionType
*type
, MonoEnumInfo
*info
)
3125 MonoDomain
*domain
= mono_object_domain (type
);
3126 MonoClass
*enumc
= mono_class_from_mono_type (type
->type
);
3127 guint j
= 0, nvalues
, crow
;
3129 MonoClassField
*field
;
3131 MONO_ARCH_SAVE_REGS
;
3133 MONO_STRUCT_SETREF (info
, utype
, mono_type_get_object (domain
, mono_class_enum_basetype (enumc
)));
3134 nvalues
= mono_class_num_fields (enumc
) ? mono_class_num_fields (enumc
) - 1 : 0;
3135 MONO_STRUCT_SETREF (info
, names
, mono_array_new (domain
, mono_defaults
.string_class
, nvalues
));
3136 MONO_STRUCT_SETREF (info
, values
, mono_array_new (domain
, enumc
, nvalues
));
3140 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3143 MonoTypeEnum def_type
;
3145 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3147 if (mono_field_is_deleted (field
))
3149 mono_array_setref (info
->names
, j
, mono_string_new (domain
, mono_field_get_name (field
)));
3151 p
= mono_class_get_field_default_value (field
, &def_type
);
3152 len
= mono_metadata_decode_blob_size (p
, &p
);
3153 switch (mono_class_enum_basetype (enumc
)->type
) {
3156 mono_array_set (info
->values
, gchar
, j
, *p
);
3158 case MONO_TYPE_CHAR
:
3161 mono_array_set (info
->values
, gint16
, j
, read16 (p
));
3165 mono_array_set (info
->values
, gint32
, j
, read32 (p
));
3169 mono_array_set (info
->values
, gint64
, j
, read64 (p
));
3172 g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc
)->type
);
3179 BFLAGS_IgnoreCase
= 1,
3180 BFLAGS_DeclaredOnly
= 2,
3181 BFLAGS_Instance
= 4,
3183 BFLAGS_Public
= 0x10,
3184 BFLAGS_NonPublic
= 0x20,
3185 BFLAGS_FlattenHierarchy
= 0x40,
3186 BFLAGS_InvokeMethod
= 0x100,
3187 BFLAGS_CreateInstance
= 0x200,
3188 BFLAGS_GetField
= 0x400,
3189 BFLAGS_SetField
= 0x800,
3190 BFLAGS_GetProperty
= 0x1000,
3191 BFLAGS_SetProperty
= 0x2000,
3192 BFLAGS_ExactBinding
= 0x10000,
3193 BFLAGS_SuppressChangeType
= 0x20000,
3194 BFLAGS_OptionalParamBinding
= 0x40000
3197 static MonoReflectionField
*
3198 ves_icall_Type_GetField (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3201 MonoClass
*startklass
, *klass
;
3203 MonoClassField
*field
;
3206 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3207 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3208 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3210 MONO_ARCH_SAVE_REGS
;
3213 mono_raise_exception (mono_get_exception_argument_null ("name"));
3214 if (type
->type
->byref
)
3217 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? mono_utf8_strcasecmp
: strcmp
;
3220 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3221 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3224 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3227 if (field
->type
== NULL
)
3229 if (mono_field_is_deleted (field
))
3231 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3232 if (bflags
& BFLAGS_Public
)
3234 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3235 if (bflags
& BFLAGS_NonPublic
) {
3242 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3243 if (bflags
& BFLAGS_Static
)
3244 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3247 if (bflags
& BFLAGS_Instance
)
3254 utf8_name
= mono_string_to_utf8 (name
);
3256 if (compare_func (mono_field_get_name (field
), utf8_name
)) {
3262 return mono_field_get_object (domain
, klass
, field
);
3264 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3271 ves_icall_Type_GetFields_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3274 MonoClass
*startklass
, *klass
, *refklass
;
3279 MonoClassField
*field
;
3280 MonoPtrArray tmp_array
;
3282 MONO_ARCH_SAVE_REGS
;
3284 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3285 if (type
->type
->byref
)
3286 return mono_array_new (domain
, mono_defaults
.field_info_class
, 0);
3287 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3288 refklass
= mono_class_from_mono_type (reftype
->type
);
3290 mono_ptr_array_init (tmp_array
, 2);
3293 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3294 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3297 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3299 if (mono_field_is_deleted (field
))
3301 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3302 if (bflags
& BFLAGS_Public
)
3304 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3305 if (bflags
& BFLAGS_NonPublic
) {
3312 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3313 if (bflags
& BFLAGS_Static
)
3314 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3317 if (bflags
& BFLAGS_Instance
)
3323 member
= (MonoObject
*)mono_field_get_object (domain
, refklass
, field
);
3324 mono_ptr_array_append (tmp_array
, member
);
3326 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3329 res
= mono_array_new_cached (domain
, mono_defaults
.field_info_class
, mono_ptr_array_size (tmp_array
));
3331 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3332 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3334 mono_ptr_array_destroy (tmp_array
);
3340 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3342 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3343 case METHOD_ATTRIBUTE_ASSEM
:
3344 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3345 case METHOD_ATTRIBUTE_PRIVATE
:
3347 case METHOD_ATTRIBUTE_PUBLIC
:
3355 ves_icall_Type_GetMethodsByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3357 static MonoClass
*MethodInfo_array
;
3359 MonoClass
*startklass
, *klass
, *refklass
;
3364 int i
, len
, match
, nslots
;
3365 /*FIXME, use MonoBitSet*/
3366 guint32 method_slots_default
[8];
3367 guint32
*method_slots
= NULL
;
3368 gchar
*mname
= NULL
;
3369 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3370 MonoVTable
*array_vtable
;
3372 MonoPtrArray tmp_array
;
3374 MONO_ARCH_SAVE_REGS
;
3376 mono_ptr_array_init (tmp_array
, 4);
3378 if (!MethodInfo_array
) {
3379 MonoClass
*klass
= mono_array_class_get (mono_defaults
.method_info_class
, 1);
3380 mono_memory_barrier ();
3381 MethodInfo_array
= klass
;
3384 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3385 array_vtable
= mono_class_vtable_full (domain
, MethodInfo_array
, TRUE
);
3386 if (type
->type
->byref
)
3387 return mono_array_new_specific (array_vtable
, 0);
3388 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3389 refklass
= mono_class_from_mono_type (reftype
->type
);
3392 mname
= mono_string_to_utf8 (name
);
3393 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3396 /* An optimization for calls made from Delegate:CreateDelegate () */
3397 if (klass
->delegate
&& mname
&& !strcmp (mname
, "Invoke") && (bflags
== (BFLAGS_Public
| BFLAGS_Static
| BFLAGS_Instance
))) {
3398 method
= mono_get_delegate_invoke (klass
);
3399 if (mono_loader_get_last_error ())
3402 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3404 res
= mono_array_new_specific (array_vtable
, 1);
3405 mono_array_setref (res
, 0, member
);
3410 mono_class_setup_vtable (klass
);
3411 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3414 if (is_generic_parameter (type
->type
))
3415 nslots
= mono_class_get_vtable_size (klass
->parent
);
3417 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : mono_class_get_vtable_size (klass
);
3418 if (nslots
>= sizeof (method_slots_default
) * 8) {
3419 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3421 method_slots
= method_slots_default
;
3422 memset (method_slots
, 0, sizeof (method_slots_default
));
3425 mono_class_setup_vtable (klass
);
3426 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3430 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3432 if (method
->slot
!= -1) {
3433 g_assert (method
->slot
< nslots
);
3434 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3436 if (!(method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
))
3437 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3440 if (method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3442 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3443 if (bflags
& BFLAGS_Public
)
3445 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3451 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3452 if (bflags
& BFLAGS_Static
)
3453 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3456 if (bflags
& BFLAGS_Instance
)
3464 if (compare_func (mname
, method
->name
))
3470 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3472 mono_ptr_array_append (tmp_array
, member
);
3474 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3478 if (method_slots
!= method_slots_default
)
3479 g_free (method_slots
);
3481 res
= mono_array_new_specific (array_vtable
, mono_ptr_array_size (tmp_array
));
3483 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3484 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3486 mono_ptr_array_destroy (tmp_array
);
3491 if (method_slots
!= method_slots_default
)
3492 g_free (method_slots
);
3493 mono_ptr_array_destroy (tmp_array
);
3494 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3495 ex
= mono_class_get_exception_for_failure (klass
);
3497 ex
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
3498 mono_loader_clear_error ();
3500 mono_raise_exception (ex
);
3505 ves_icall_Type_GetConstructors_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3508 static MonoClass
*System_Reflection_ConstructorInfo
;
3509 MonoClass
*startklass
, *klass
, *refklass
;
3514 gpointer iter
= NULL
;
3515 MonoPtrArray tmp_array
;
3517 MONO_ARCH_SAVE_REGS
;
3519 mono_ptr_array_init (tmp_array
, 4); /*FIXME, guestimating*/
3521 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3522 if (type
->type
->byref
)
3523 return mono_array_new_cached (domain
, mono_defaults
.method_info_class
, 0);
3524 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3525 refklass
= mono_class_from_mono_type (reftype
->type
);
3527 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3528 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3530 if (!System_Reflection_ConstructorInfo
)
3531 System_Reflection_ConstructorInfo
= mono_class_from_name (
3532 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
3535 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3537 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
3539 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3540 if (bflags
& BFLAGS_Public
)
3543 if (bflags
& BFLAGS_NonPublic
)
3549 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3550 if (bflags
& BFLAGS_Static
)
3551 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3554 if (bflags
& BFLAGS_Instance
)
3560 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3562 mono_ptr_array_append (tmp_array
, member
);
3565 res
= mono_array_new_cached (domain
, System_Reflection_ConstructorInfo
, mono_ptr_array_size (tmp_array
));
3567 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3568 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3570 mono_ptr_array_destroy (tmp_array
);
3576 property_hash (gconstpointer data
)
3578 MonoProperty
*prop
= (MonoProperty
*)data
;
3580 return g_str_hash (prop
->name
);
3584 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
3586 // Properties are hide-by-name-and-signature
3587 if (!g_str_equal (prop1
->name
, prop2
->name
))
3590 if (prop1
->get
&& prop2
->get
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->get
), mono_method_signature (prop2
->get
)))
3592 if (prop1
->set
&& prop2
->set
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->set
), mono_method_signature (prop2
->set
)))
3598 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
3603 return method_nonpublic (accessor
, start_klass
);
3607 ves_icall_Type_GetPropertiesByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3610 static MonoClass
*System_Reflection_PropertyInfo
;
3611 MonoClass
*startklass
, *klass
;
3617 gchar
*propname
= NULL
;
3618 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3620 GHashTable
*properties
;
3621 MonoPtrArray tmp_array
;
3623 MONO_ARCH_SAVE_REGS
;
3625 mono_ptr_array_init (tmp_array
, 8); /*This the average for ASP.NET types*/
3627 if (!System_Reflection_PropertyInfo
)
3628 System_Reflection_PropertyInfo
= mono_class_from_name (
3629 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
3631 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3632 if (type
->type
->byref
)
3633 return mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, 0);
3634 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3636 propname
= mono_string_to_utf8 (name
);
3637 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3640 mono_class_setup_vtable (klass
);
3642 properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
3644 mono_class_setup_vtable (klass
);
3645 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3646 g_hash_table_destroy (properties
);
3649 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3653 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
3659 flags
= method
->flags
;
3662 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
3663 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
3664 if (bflags
& BFLAGS_Public
)
3666 } else if (bflags
& BFLAGS_NonPublic
) {
3667 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
3668 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
3675 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
3676 if (bflags
& BFLAGS_Static
)
3677 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3680 if (bflags
& BFLAGS_Instance
)
3689 if (compare_func (propname
, prop
->name
))
3693 if (g_hash_table_lookup (properties
, prop
))
3696 mono_ptr_array_append (tmp_array
, mono_property_get_object (domain
, startklass
, prop
));
3698 g_hash_table_insert (properties
, prop
, prop
);
3700 if ((!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
)))
3703 g_hash_table_destroy (properties
);
3706 res
= mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, mono_ptr_array_size (tmp_array
));
3707 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3708 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3710 mono_ptr_array_destroy (tmp_array
);
3715 static MonoReflectionEvent
*
3716 ves_icall_MonoType_GetEvent (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3719 MonoClass
*klass
, *startklass
;
3725 MONO_ARCH_SAVE_REGS
;
3727 event_name
= mono_string_to_utf8 (name
);
3728 if (type
->type
->byref
)
3730 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3731 domain
= mono_object_domain (type
);
3734 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3735 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3738 while ((event
= mono_class_get_events (klass
, &iter
))) {
3739 if (strcmp (event
->name
, event_name
))
3742 method
= event
->add
;
3744 method
= event
->remove
;
3746 method
= event
->raise
;
3748 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3749 if (!(bflags
& BFLAGS_Public
))
3752 if (!(bflags
& BFLAGS_NonPublic
))
3754 if ((klass
!= startklass
) && (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PRIVATE
)
3758 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3759 if (!(bflags
& BFLAGS_Static
))
3761 if (!(bflags
& BFLAGS_FlattenHierarchy
) && (klass
!= startklass
))
3764 if (!(bflags
& BFLAGS_Instance
))
3768 if (!(bflags
& BFLAGS_NonPublic
))
3771 g_free (event_name
);
3772 return mono_event_get_object (domain
, startklass
, event
);
3775 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3778 g_free (event_name
);
3783 ves_icall_Type_GetEvents_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3786 static MonoClass
*System_Reflection_EventInfo
;
3787 MonoClass
*startklass
, *klass
;
3794 MonoPtrArray tmp_array
;
3796 MONO_ARCH_SAVE_REGS
;
3798 mono_ptr_array_init (tmp_array
, 4);
3800 if (!System_Reflection_EventInfo
)
3801 System_Reflection_EventInfo
= mono_class_from_name (
3802 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
3804 domain
= mono_object_domain (type
);
3805 if (type
->type
->byref
)
3806 return mono_array_new_cached (domain
, System_Reflection_EventInfo
, 0);
3807 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3810 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3811 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3814 while ((event
= mono_class_get_events (klass
, &iter
))) {
3816 method
= event
->add
;
3818 method
= event
->remove
;
3820 method
= event
->raise
;
3822 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3823 if (bflags
& BFLAGS_Public
)
3825 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
3826 if (bflags
& BFLAGS_NonPublic
)
3831 if (bflags
& BFLAGS_NonPublic
)
3837 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3838 if (bflags
& BFLAGS_Static
)
3839 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3842 if (bflags
& BFLAGS_Instance
)
3847 if (bflags
& BFLAGS_Instance
)
3851 mono_ptr_array_append (tmp_array
, mono_event_get_object (domain
, startklass
, event
));
3853 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3856 res
= mono_array_new_cached (domain
, System_Reflection_EventInfo
, mono_ptr_array_size (tmp_array
));
3858 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3859 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3861 mono_ptr_array_destroy (tmp_array
);
3866 static MonoReflectionType
*
3867 ves_icall_Type_GetNestedType (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3875 MONO_ARCH_SAVE_REGS
;
3878 mono_raise_exception (mono_get_exception_argument_null ("name"));
3880 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3881 if (type
->type
->byref
)
3883 klass
= mono_class_from_mono_type (type
->type
);
3884 str
= mono_string_to_utf8 (name
);
3887 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3888 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3891 * If a nested type is generic, return its generic type definition.
3892 * Note that this means that the return value is essentially a
3893 * nested type of the generic type definition of @klass.
3895 * A note in MSDN claims that a generic type definition can have
3896 * nested types that aren't generic. In any case, the container of that
3897 * nested type would be the generic type definition.
3899 if (klass
->generic_class
)
3900 klass
= klass
->generic_class
->container_class
;
3903 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
3905 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
3906 if (bflags
& BFLAGS_Public
)
3909 if (bflags
& BFLAGS_NonPublic
)
3914 if (strcmp (nested
->name
, str
) == 0){
3916 return mono_type_get_object (domain
, &nested
->byval_arg
);
3919 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3926 ves_icall_Type_GetNestedTypes (MonoReflectionType
*type
, guint32 bflags
)
3935 MonoPtrArray tmp_array
;
3937 MONO_ARCH_SAVE_REGS
;
3939 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3940 if (type
->type
->byref
)
3941 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
3942 klass
= mono_class_from_mono_type (type
->type
);
3943 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3944 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3947 * If a nested type is generic, return its generic type definition.
3948 * Note that this means that the return value is essentially the set
3949 * of nested types of the generic type definition of @klass.
3951 * A note in MSDN claims that a generic type definition can have
3952 * nested types that aren't generic. In any case, the container of that
3953 * nested type would be the generic type definition.
3955 if (klass
->generic_class
)
3956 klass
= klass
->generic_class
->container_class
;
3958 mono_ptr_array_init (tmp_array
, 1);
3960 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
3962 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
3963 if (bflags
& BFLAGS_Public
)
3966 if (bflags
& BFLAGS_NonPublic
)
3971 member
= (MonoObject
*)mono_type_get_object (domain
, &nested
->byval_arg
);
3972 mono_ptr_array_append (tmp_array
, member
);
3975 res
= mono_array_new_cached (domain
, mono_defaults
.monotype_class
, mono_ptr_array_size (tmp_array
));
3977 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3978 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3980 mono_ptr_array_destroy (tmp_array
);
3985 static MonoReflectionType
*
3986 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly
*assembly
, MonoReflectionModule
*module
, MonoString
*name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
)
3989 MonoType
*type
= NULL
;
3990 MonoTypeNameParse info
;
3991 gboolean type_resolve
;
3993 MONO_ARCH_SAVE_REGS
;
3995 /* On MS.NET, this does not fire a TypeResolve event */
3996 type_resolve
= TRUE
;
3997 str
= mono_string_to_utf8 (name
);
3998 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3999 if (!mono_reflection_parse_type (str
, &info
)) {
4001 mono_reflection_free_type_info (&info
);
4002 if (throwOnError
) /* uhm: this is a parse error, though... */
4003 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4004 /*g_print ("failed parse\n");*/
4008 if (info
.assembly
.name
) {
4010 mono_reflection_free_type_info (&info
);
4012 /* 1.0 and 2.0 throw different exceptions */
4013 if (mono_defaults
.generic_ilist_class
)
4014 mono_raise_exception (mono_get_exception_argument (NULL
, "Type names passed to Assembly.GetType() must not specify an assembly."));
4016 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4021 if (module
!= NULL
) {
4023 type
= mono_reflection_get_type (module
->image
, &info
, ignoreCase
, &type_resolve
);
4028 if (assembly
->assembly
->dynamic
) {
4029 /* Enumerate all modules */
4030 MonoReflectionAssemblyBuilder
*abuilder
= (MonoReflectionAssemblyBuilder
*)assembly
;
4034 if (abuilder
->modules
) {
4035 for (i
= 0; i
< mono_array_length (abuilder
->modules
); ++i
) {
4036 MonoReflectionModuleBuilder
*mb
= mono_array_get (abuilder
->modules
, MonoReflectionModuleBuilder
*, i
);
4037 type
= mono_reflection_get_type (&mb
->dynamic_image
->image
, &info
, ignoreCase
, &type_resolve
);
4043 if (!type
&& abuilder
->loaded_modules
) {
4044 for (i
= 0; i
< mono_array_length (abuilder
->loaded_modules
); ++i
) {
4045 MonoReflectionModule
*mod
= mono_array_get (abuilder
->loaded_modules
, MonoReflectionModule
*, i
);
4046 type
= mono_reflection_get_type (mod
->image
, &info
, ignoreCase
, &type_resolve
);
4053 type
= mono_reflection_get_type (assembly
->assembly
->image
, &info
, ignoreCase
, &type_resolve
);
4055 mono_reflection_free_type_info (&info
);
4057 MonoException
*e
= NULL
;
4060 e
= mono_get_exception_type_load (name
, NULL
);
4062 if (mono_loader_get_last_error () && mono_defaults
.generic_ilist_class
)
4063 e
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
4065 mono_loader_clear_error ();
4068 mono_raise_exception (e
);
4073 if (type
->type
== MONO_TYPE_CLASS
) {
4074 MonoClass
*klass
= mono_type_get_class (type
);
4076 if (mono_is_security_manager_active () && !klass
->exception_type
)
4077 /* Some security problems are detected during generic vtable construction */
4078 mono_class_setup_vtable (klass
);
4079 /* need to report exceptions ? */
4080 if (throwOnError
&& klass
->exception_type
) {
4081 /* report SecurityException (or others) that occured when loading the assembly */
4082 MonoException
*exc
= mono_class_get_exception_for_failure (klass
);
4083 mono_loader_clear_error ();
4084 mono_raise_exception (exc
);
4085 } else if (klass
->exception_type
== MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND
) {
4090 /* g_print ("got it\n"); */
4091 return mono_type_get_object (mono_object_domain (assembly
), type
);
4095 replace_shadow_path (MonoDomain
*domain
, gchar
*dirname
, gchar
**filename
)
4098 gchar
*shadow_ini_file
;
4101 /* Check for shadow-copied assembly */
4102 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4103 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4105 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4106 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4112 g_free (shadow_ini_file
);
4113 if (content
!= NULL
) {
4116 *filename
= content
;
4124 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly
*assembly
, MonoBoolean escaped
)
4126 MonoDomain
*domain
= mono_object_domain (assembly
);
4127 MonoAssembly
*mass
= assembly
->assembly
;
4128 MonoString
*res
= NULL
;
4133 MONO_ARCH_SAVE_REGS
;
4135 if (g_path_is_absolute (mass
->image
->name
)) {
4136 absolute
= g_strdup (mass
->image
->name
);
4137 dirname
= g_path_get_dirname (absolute
);
4139 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4140 dirname
= g_strdup (mass
->basedir
);
4143 replace_shadow_path (domain
, dirname
, &absolute
);
4148 for (i
= strlen (absolute
) - 1; i
>= 0; i
--)
4149 if (absolute
[i
] == '\\')
4154 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4156 const char *prepend
= "file://";
4158 if (*absolute
== '/' && *(absolute
+ 1) == '/') {
4161 prepend
= "file:///";
4164 uri
= g_strconcat (prepend
, absolute
, NULL
);
4168 res
= mono_string_new (domain
, uri
);
4176 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly
*assembly
)
4178 MonoAssembly
*mass
= assembly
->assembly
;
4180 MONO_ARCH_SAVE_REGS
;
4182 return mass
->in_gac
;
4185 static MonoReflectionAssembly
*
4186 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString
*mname
, MonoObject
*evidence
)
4190 MonoImageOpenStatus status
;
4192 MONO_ARCH_SAVE_REGS
;
4194 name
= mono_string_to_utf8 (mname
);
4195 res
= mono_assembly_load_with_partial_name (name
, &status
);
4201 return mono_assembly_get_object (mono_domain_get (), res
);
4205 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly
*assembly
)
4207 MonoDomain
*domain
= mono_object_domain (assembly
);
4210 MONO_ARCH_SAVE_REGS
;
4212 res
= mono_string_new (domain
, mono_image_get_filename (assembly
->assembly
->image
));
4218 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
*assembly
)
4220 MONO_ARCH_SAVE_REGS
;
4222 return assembly
->assembly
->ref_only
;
4226 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly
*assembly
)
4228 MonoDomain
*domain
= mono_object_domain (assembly
);
4230 MONO_ARCH_SAVE_REGS
;
4232 return mono_string_new (domain
, assembly
->assembly
->image
->version
);
4235 static MonoReflectionMethod
*
4236 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly
*assembly
)
4238 guint32 token
= mono_image_get_entry_point (assembly
->assembly
->image
);
4240 MONO_ARCH_SAVE_REGS
;
4244 return mono_method_get_object (mono_object_domain (assembly
), mono_get_method (assembly
->assembly
->image
, token
, NULL
), NULL
);
4247 static MonoReflectionModule
*
4248 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly
*assembly
)
4250 return mono_module_get_object (mono_object_domain (assembly
), assembly
->assembly
->image
);
4254 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly
*assembly
)
4256 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4257 MonoArray
*result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, table
->rows
);
4261 MONO_ARCH_SAVE_REGS
;
4263 for (i
= 0; i
< table
->rows
; ++i
) {
4264 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4265 mono_array_setref (result
, i
, mono_string_new (mono_object_domain (assembly
), val
));
4271 create_version (MonoDomain
*domain
, guint32 major
, guint32 minor
, guint32 build
, guint32 revision
)
4273 static MonoClass
*System_Version
= NULL
;
4274 static MonoMethod
*create_version
= NULL
;
4278 if (!System_Version
) {
4279 System_Version
= mono_class_from_name (mono_defaults
.corlib
, "System", "Version");
4280 g_assert (System_Version
);
4283 if (!create_version
) {
4284 MonoMethodDesc
*desc
= mono_method_desc_new (":.ctor(int,int,int,int)", FALSE
);
4285 create_version
= mono_method_desc_search_in_class (desc
, System_Version
);
4286 g_assert (create_version
);
4287 mono_method_desc_free (desc
);
4293 args
[3] = &revision
;
4294 result
= mono_object_new (domain
, System_Version
);
4295 mono_runtime_invoke (create_version
, result
, args
, NULL
);
4301 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly
*assembly
)
4303 static MonoClass
*System_Reflection_AssemblyName
;
4305 MonoDomain
*domain
= mono_object_domain (assembly
);
4307 static MonoMethod
*create_culture
= NULL
;
4308 MonoImage
*image
= assembly
->assembly
->image
;
4311 MONO_ARCH_SAVE_REGS
;
4313 if (!System_Reflection_AssemblyName
)
4314 System_Reflection_AssemblyName
= mono_class_from_name (
4315 mono_defaults
.corlib
, "System.Reflection", "AssemblyName");
4317 t
= &assembly
->assembly
->image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4320 result
= mono_array_new (domain
, System_Reflection_AssemblyName
, count
);
4322 if (count
> 0 && !create_culture
) {
4323 MonoMethodDesc
*desc
= mono_method_desc_new (
4324 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4325 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4326 g_assert (create_culture
);
4327 mono_method_desc_free (desc
);
4330 for (i
= 0; i
< count
; i
++) {
4331 MonoReflectionAssemblyName
*aname
;
4332 guint32 cols
[MONO_ASSEMBLYREF_SIZE
];
4334 mono_metadata_decode_row (t
, i
, cols
, MONO_ASSEMBLYREF_SIZE
);
4336 aname
= (MonoReflectionAssemblyName
*) mono_object_new (
4337 domain
, System_Reflection_AssemblyName
);
4339 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_NAME
])));
4341 aname
->major
= cols
[MONO_ASSEMBLYREF_MAJOR_VERSION
];
4342 aname
->minor
= cols
[MONO_ASSEMBLYREF_MINOR_VERSION
];
4343 aname
->build
= cols
[MONO_ASSEMBLYREF_BUILD_NUMBER
];
4344 aname
->revision
= cols
[MONO_ASSEMBLYREF_REV_NUMBER
];
4345 aname
->flags
= cols
[MONO_ASSEMBLYREF_FLAGS
];
4346 aname
->versioncompat
= 1; /* SameMachine (default) */
4347 aname
->hashalg
= ASSEMBLY_HASH_SHA1
; /* SHA1 (default) */
4348 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, aname
->major
, aname
->minor
, aname
->build
, aname
->revision
));
4350 if (create_culture
) {
4352 MonoBoolean assembly_ref
= 1;
4353 args
[0] = mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_CULTURE
]));
4354 args
[1] = &assembly_ref
;
4355 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4358 if (cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]) {
4359 const gchar
*pkey_ptr
= mono_metadata_blob_heap (image
, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]);
4360 guint32 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4362 if ((cols
[MONO_ASSEMBLYREF_FLAGS
] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
)) {
4363 /* public key token isn't copied - the class library will
4364 automatically generate it from the public key if required */
4365 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4366 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4368 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4369 memcpy (mono_array_addr (aname
->keyToken
, guint8
, 0), pkey_ptr
, pkey_len
);
4372 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4375 /* note: this function doesn't return the codebase on purpose (i.e. it can
4376 be used under partial trust as path information isn't present). */
4378 mono_array_setref (result
, i
, aname
);
4389 foreach_namespace (const char* key
, gconstpointer val
, NameSpaceInfo
*info
)
4391 MonoString
*name
= mono_string_new (mono_object_domain (info
->res
), key
);
4393 mono_array_setref (info
->res
, info
->idx
, name
);
4398 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly
*assembly
)
4400 MonoImage
*img
= assembly
->assembly
->image
;
4405 MONO_ARCH_SAVE_REGS
;
4407 mono_image_lock (img
);
4408 mono_image_init_name_cache (img
);
4411 len
= g_hash_table_size (img
->name_cache
);
4412 mono_image_unlock (img
);
4414 /*we can't create objects holding the image lock */
4415 res
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, len
);
4417 mono_image_lock (img
);
4418 /*len might have changed, create a new array*/
4419 if (len
!= g_hash_table_size (img
->name_cache
))
4424 g_hash_table_foreach (img
->name_cache
, (GHFunc
)foreach_namespace
, &info
);
4425 mono_image_unlock (img
);
4430 /* move this in some file in mono/util/ */
4432 g_concat_dir_and_file (const char *dir
, const char *file
)
4434 g_return_val_if_fail (dir
!= NULL
, NULL
);
4435 g_return_val_if_fail (file
!= NULL
, NULL
);
4438 * If the directory name doesn't have a / on the end, we need
4439 * to add one so we get a proper path to the file
4441 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4442 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4444 return g_strconcat (dir
, file
, NULL
);
4448 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, gint32
*size
, MonoReflectionModule
**ref_module
)
4450 char *n
= mono_string_to_utf8 (name
);
4451 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4453 guint32 cols
[MONO_MANIFEST_SIZE
];
4454 guint32 impl
, file_idx
;
4458 MONO_ARCH_SAVE_REGS
;
4460 for (i
= 0; i
< table
->rows
; ++i
) {
4461 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4462 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4463 if (strcmp (val
, n
) == 0)
4467 if (i
== table
->rows
)
4470 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4473 * this code should only be called after obtaining the
4474 * ResourceInfo and handling the other cases.
4476 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4477 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4479 module
= mono_image_load_file_for_image (assembly
->assembly
->image
, file_idx
);
4484 module
= assembly
->assembly
->image
;
4486 mono_gc_wbarrier_generic_store (ref_module
, (MonoObject
*) mono_module_get_object (mono_domain_get (), module
));
4488 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4492 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoManifestResourceInfo
*info
)
4494 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4496 guint32 cols
[MONO_MANIFEST_SIZE
];
4497 guint32 file_cols
[MONO_FILE_SIZE
];
4501 MONO_ARCH_SAVE_REGS
;
4503 n
= mono_string_to_utf8 (name
);
4504 for (i
= 0; i
< table
->rows
; ++i
) {
4505 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4506 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4507 if (strcmp (val
, n
) == 0)
4511 if (i
== table
->rows
)
4514 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4515 info
->location
= RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
;
4518 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4519 case MONO_IMPLEMENTATION_FILE
:
4520 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4521 table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4522 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4523 val
= mono_metadata_string_heap (assembly
->assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4524 MONO_OBJECT_SETREF (info
, filename
, mono_string_new (mono_object_domain (assembly
), val
));
4525 if (file_cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4528 info
->location
= RESOURCE_LOCATION_EMBEDDED
;
4531 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4532 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4533 mono_assembly_load_reference (assembly
->assembly
->image
, i
- 1);
4534 if (assembly
->assembly
->image
->references
[i
- 1] == (gpointer
)-1) {
4535 char *msg
= g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->assembly
->image
->name
);
4536 MonoException
*ex
= mono_get_exception_file_not_found2 (msg
, NULL
);
4538 mono_raise_exception (ex
);
4540 MONO_OBJECT_SETREF (info
, assembly
, mono_assembly_get_object (mono_domain_get (), assembly
->assembly
->image
->references
[i
- 1]));
4542 /* Obtain info recursively */
4543 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info
->assembly
, name
, info
);
4544 info
->location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4547 case MONO_IMPLEMENTATION_EXP_TYPE
:
4548 g_assert_not_reached ();
4557 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoBoolean resource_modules
)
4559 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4560 MonoArray
*result
= NULL
;
4565 MONO_ARCH_SAVE_REGS
;
4567 /* check hash if needed */
4569 n
= mono_string_to_utf8 (name
);
4570 for (i
= 0; i
< table
->rows
; ++i
) {
4571 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4572 if (strcmp (val
, n
) == 0) {
4575 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4576 fn
= mono_string_new (mono_object_domain (assembly
), n
);
4578 return (MonoObject
*)fn
;
4586 for (i
= 0; i
< table
->rows
; ++i
) {
4587 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
4591 result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, count
);
4594 for (i
= 0; i
< table
->rows
; ++i
) {
4595 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
4596 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4597 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4598 mono_array_setref (result
, count
, mono_string_new (mono_object_domain (assembly
), n
));
4603 return (MonoObject
*)result
;
4607 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
*assembly
)
4609 MonoDomain
*domain
= mono_domain_get();
4612 int i
, j
, file_count
= 0;
4613 MonoImage
**modules
;
4614 guint32 module_count
, real_module_count
;
4615 MonoTableInfo
*table
;
4616 guint32 cols
[MONO_FILE_SIZE
];
4617 MonoImage
*image
= assembly
->assembly
->image
;
4619 g_assert (image
!= NULL
);
4620 g_assert (!assembly
->assembly
->dynamic
);
4622 table
= &image
->tables
[MONO_TABLE_FILE
];
4623 file_count
= table
->rows
;
4625 modules
= image
->modules
;
4626 module_count
= image
->module_count
;
4628 real_module_count
= 0;
4629 for (i
= 0; i
< module_count
; ++i
)
4631 real_module_count
++;
4633 klass
= mono_class_from_name (mono_defaults
.corlib
, "System.Reflection", "Module");
4634 res
= mono_array_new (domain
, klass
, 1 + real_module_count
+ file_count
);
4636 mono_array_setref (res
, 0, mono_module_get_object (domain
, image
));
4638 for (i
= 0; i
< module_count
; ++i
)
4640 mono_array_setref (res
, j
, mono_module_get_object (domain
, modules
[i
]));
4644 for (i
= 0; i
< file_count
; ++i
, ++j
) {
4645 mono_metadata_decode_row (table
, i
, cols
, MONO_FILE_SIZE
);
4646 if (cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4647 mono_array_setref (res
, j
, mono_module_file_get_object (domain
, image
, i
));
4649 MonoImage
*m
= mono_image_load_file_for_image (image
, i
+ 1);
4651 MonoString
*fname
= mono_string_new (mono_domain_get (), mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]));
4652 mono_raise_exception (mono_get_exception_file_not_found2 (NULL
, fname
));
4654 mono_array_setref (res
, j
, mono_module_get_object (domain
, m
));
4661 static MonoReflectionMethod
*
4662 ves_icall_GetCurrentMethod (void)
4664 MonoMethod
*m
= mono_method_get_last_managed ();
4666 while (m
->is_inflated
)
4667 m
= ((MonoMethodInflated
*)m
)->declaring
;
4669 return mono_method_get_object (mono_domain_get (), m
, NULL
);
4674 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
4677 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
4678 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
4679 //method is inflated, we should inflate it on the other class
4680 MonoGenericContext ctx
;
4681 ctx
.method_inst
= inflated
->context
.method_inst
;
4682 ctx
.class_inst
= inflated
->context
.class_inst
;
4683 if (klass
->generic_class
)
4684 ctx
.class_inst
= klass
->generic_class
->context
.class_inst
;
4685 else if (klass
->generic_container
)
4686 ctx
.class_inst
= klass
->generic_container
->context
.class_inst
;
4687 return mono_class_inflate_generic_method_full (inflated
->declaring
, klass
, &ctx
);
4690 mono_class_setup_methods (method
->klass
);
4691 if (method
->klass
->exception_type
)
4693 for (i
= 0; i
< method
->klass
->method
.count
; ++i
) {
4694 if (method
->klass
->methods
[i
] == method
) {
4699 mono_class_setup_methods (klass
);
4700 if (klass
->exception_type
)
4702 g_assert (offset
>= 0 && offset
< klass
->method
.count
);
4703 return klass
->methods
[offset
];
4706 static MonoReflectionMethod
*
4707 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod
*method
, MonoType
*type
)
4711 klass
= mono_class_from_mono_type (type
);
4712 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
4714 if (method
->klass
!= klass
) {
4715 method
= mono_method_get_equivalent_method (method
, klass
);
4720 klass
= method
->klass
;
4721 return mono_method_get_object (mono_domain_get (), method
, klass
);
4724 static MonoReflectionMethod
*
4725 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod
*method
)
4727 return mono_method_get_object (mono_domain_get (), method
, NULL
);
4730 static MonoReflectionMethodBody
*
4731 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
)
4733 return mono_method_body_get_object (mono_domain_get (), method
);
4736 static MonoReflectionAssembly
*
4737 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4739 MonoMethod
*dest
= NULL
;
4741 MONO_ARCH_SAVE_REGS
;
4743 mono_stack_walk_no_il (get_executing
, &dest
);
4744 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4748 static MonoReflectionAssembly
*
4749 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4751 MonoDomain
* domain
= mono_domain_get ();
4753 MONO_ARCH_SAVE_REGS
;
4755 if (!domain
->entry_assembly
)
4758 return mono_assembly_get_object (domain
, domain
->entry_assembly
);
4761 static MonoReflectionAssembly
*
4762 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4767 MONO_ARCH_SAVE_REGS
;
4770 mono_stack_walk_no_il (get_executing
, &dest
);
4772 mono_stack_walk_no_il (get_caller
, &dest
);
4775 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4779 ves_icall_System_MonoType_getFullName (MonoReflectionType
*object
, gboolean full_name
,
4780 gboolean assembly_qualified
)
4782 MonoDomain
*domain
= mono_object_domain (object
);
4783 MonoTypeNameFormat format
;
4787 MONO_ARCH_SAVE_REGS
;
4789 format
= assembly_qualified
?
4790 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
4791 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
4793 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
4795 name
= mono_type_get_name_full (object
->type
, format
);
4799 if (full_name
&& (object
->type
->type
== MONO_TYPE_VAR
|| object
->type
->type
== MONO_TYPE_MVAR
)) {
4804 res
= mono_string_new (domain
, name
);
4811 vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType
*this)
4813 MonoClass
*klass
= mono_class_from_mono_type (this->type
);
4814 return mono_security_core_clr_class_level (klass
);
4818 fill_reflection_assembly_name (MonoDomain
*domain
, MonoReflectionAssemblyName
*aname
, MonoAssemblyName
*name
, const char *absolute
, gboolean by_default_version
, gboolean default_publickey
, gboolean default_token
)
4820 static MonoMethod
*create_culture
= NULL
;
4823 const char *pkey_ptr
;
4825 MonoBoolean assembly_ref
= 0;
4827 MONO_ARCH_SAVE_REGS
;
4829 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, name
->name
));
4830 aname
->major
= name
->major
;
4831 aname
->minor
= name
->minor
;
4832 aname
->build
= name
->build
;
4833 aname
->flags
= name
->flags
;
4834 aname
->revision
= name
->revision
;
4835 aname
->hashalg
= name
->hash_alg
;
4836 aname
->versioncompat
= 1; /* SameMachine (default) */
4838 if (by_default_version
)
4839 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, name
->major
, name
->minor
, name
->build
, name
->revision
));
4842 if (absolute
!= NULL
&& *absolute
!= '\0') {
4843 const gchar
*prepend
= "file://";
4846 codebase
= g_strdup (absolute
);
4851 for (i
= strlen (codebase
) - 1; i
>= 0; i
--)
4852 if (codebase
[i
] == '\\')
4855 if (*codebase
== '/' && *(codebase
+ 1) == '/') {
4858 prepend
= "file:///";
4862 result
= g_strconcat (prepend
, codebase
, NULL
);
4868 MONO_OBJECT_SETREF (aname
, codebase
, mono_string_new (domain
, codebase
));
4872 if (!create_culture
) {
4873 MonoMethodDesc
*desc
= mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4874 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4875 g_assert (create_culture
);
4876 mono_method_desc_free (desc
);
4879 if (name
->culture
) {
4880 args
[0] = mono_string_new (domain
, name
->culture
);
4881 args
[1] = &assembly_ref
;
4882 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4885 if (name
->public_key
) {
4886 pkey_ptr
= (char*)name
->public_key
;
4887 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4889 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4890 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4891 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4892 } else if (default_publickey
) {
4893 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4894 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4897 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4898 if (name
->public_key_token
[0]) {
4902 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 8));
4903 p
= mono_array_addr (aname
->keyToken
, char, 0);
4905 for (i
= 0, j
= 0; i
< 8; i
++) {
4906 *p
= g_ascii_xdigit_value (name
->public_key_token
[j
++]) << 4;
4907 *p
|= g_ascii_xdigit_value (name
->public_key_token
[j
++]);
4910 } else if (default_token
) {
4911 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4916 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly
*assembly
)
4918 MonoDomain
*domain
= mono_object_domain (assembly
);
4919 MonoAssembly
*mass
= assembly
->assembly
;
4923 name
= g_strdup_printf (
4924 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4926 mass
->aname
.major
, mass
->aname
.minor
, mass
->aname
.build
, mass
->aname
.revision
,
4927 mass
->aname
.culture
&& *mass
->aname
.culture
? mass
->aname
.culture
: "neutral",
4928 mass
->aname
.public_key_token
[0] ? (char *)mass
->aname
.public_key_token
: "null",
4929 (mass
->aname
.flags
& ASSEMBLYREF_RETARGETABLE_FLAG
) ? ", Retargetable=Yes" : "");
4931 res
= mono_string_new (domain
, name
);
4938 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly
*assembly
, MonoReflectionAssemblyName
*aname
)
4941 MonoAssembly
*mass
= assembly
->assembly
;
4943 MONO_ARCH_SAVE_REGS
;
4945 if (g_path_is_absolute (mass
->image
->name
)) {
4946 fill_reflection_assembly_name (mono_object_domain (assembly
),
4947 aname
, &mass
->aname
, mass
->image
->name
, TRUE
,
4951 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4953 fill_reflection_assembly_name (mono_object_domain (assembly
),
4954 aname
, &mass
->aname
, absolute
, TRUE
, TRUE
,
4961 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString
*fname
, MonoReflectionAssemblyName
*aname
)
4964 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
4967 MonoAssemblyName name
;
4970 MONO_ARCH_SAVE_REGS
;
4972 filename
= mono_string_to_utf8 (fname
);
4974 dirname
= g_path_get_dirname (filename
);
4975 replace_shadow_path (mono_domain_get (), dirname
, &filename
);
4978 image
= mono_image_open (filename
, &status
);
4984 if (status
== MONO_IMAGE_IMAGE_INVALID
)
4985 exc
= mono_get_exception_bad_image_format2 (NULL
, fname
);
4987 exc
= mono_get_exception_file_not_found2 (NULL
, fname
);
4988 mono_raise_exception (exc
);
4991 res
= mono_assembly_fill_assembly_name (image
, &name
);
4993 mono_image_close (image
);
4995 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4998 fill_reflection_assembly_name (mono_domain_get (), aname
, &name
, filename
,
5002 mono_image_close (image
);
5006 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly
*assembly
,
5007 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
)
5009 MonoBoolean result
= FALSE
;
5010 MonoDeclSecurityEntry entry
;
5012 /* SecurityAction.RequestMinimum */
5013 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5014 *minimum
= entry
.blob
;
5015 *minLength
= entry
.size
;
5018 /* SecurityAction.RequestOptional */
5019 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5020 *optional
= entry
.blob
;
5021 *optLength
= entry
.size
;
5024 /* SecurityAction.RequestRefuse */
5025 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5026 *refused
= entry
.blob
;
5027 *refLength
= entry
.size
;
5035 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArray
**exceptions
, MonoBoolean exportedOnly
)
5039 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5041 guint32 attrs
, visibility
;
5043 /* we start the count from 1 because we skip the special type <Module> */
5046 for (i
= 1; i
< tdef
->rows
; ++i
) {
5047 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5048 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5049 if (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5053 count
= tdef
->rows
- 1;
5055 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
5056 *exceptions
= mono_array_new (domain
, mono_defaults
.exception_class
, count
);
5058 for (i
= 1; i
< tdef
->rows
; ++i
) {
5059 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5060 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5061 if (!exportedOnly
|| (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)) {
5062 klass
= mono_class_get (image
, (i
+ 1) | MONO_TOKEN_TYPE_DEF
);
5064 mono_array_setref (res
, count
, mono_type_get_object (domain
, &klass
->byval_arg
));
5066 MonoLoaderError
*error
;
5069 error
= mono_loader_get_last_error ();
5070 g_assert (error
!= NULL
);
5072 ex
= mono_loader_error_prepare_exception (error
);
5073 mono_array_setref (*exceptions
, count
, ex
);
5075 if (mono_loader_get_last_error ())
5076 mono_loader_clear_error ();
5085 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly
*assembly
, MonoBoolean exportedOnly
)
5087 MonoArray
*res
= NULL
;
5088 MonoArray
*exceptions
= NULL
;
5089 MonoImage
*image
= NULL
;
5090 MonoTableInfo
*table
= NULL
;
5093 int i
, len
, ex_count
;
5095 MONO_ARCH_SAVE_REGS
;
5097 domain
= mono_object_domain (assembly
);
5099 g_assert (!assembly
->assembly
->dynamic
);
5100 image
= assembly
->assembly
->image
;
5101 table
= &image
->tables
[MONO_TABLE_FILE
];
5102 res
= mono_module_get_types (domain
, image
, &exceptions
, exportedOnly
);
5104 /* Append data from all modules in the assembly */
5105 for (i
= 0; i
< table
->rows
; ++i
) {
5106 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5107 MonoImage
*loaded_image
= mono_assembly_load_module (image
->assembly
, i
+ 1);
5110 MonoArray
*res2
= mono_module_get_types (domain
, loaded_image
, &ex2
, exportedOnly
);
5111 /* Append the new types to the end of the array */
5112 if (mono_array_length (res2
) > 0) {
5114 MonoArray
*res3
, *ex3
;
5116 len1
= mono_array_length (res
);
5117 len2
= mono_array_length (res2
);
5119 res3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5120 mono_array_memcpy_refs (res3
, 0, res
, 0, len1
);
5121 mono_array_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5124 ex3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5125 mono_array_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5126 mono_array_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5133 /* the ReflectionTypeLoadException must have all the types (Types property),
5134 * NULL replacing types which throws an exception. The LoaderException must
5135 * contain all exceptions for NULL items.
5138 len
= mono_array_length (res
);
5141 for (i
= 0; i
< len
; i
++) {
5142 MonoReflectionType
*t
= mono_array_get (res
, gpointer
, i
);
5146 klass
= mono_type_get_class (t
->type
);
5147 if ((klass
!= NULL
) && klass
->exception_type
) {
5148 /* keep the class in the list */
5149 list
= g_list_append (list
, klass
);
5150 /* and replace Type with NULL */
5151 mono_array_setref (res
, i
, NULL
);
5158 if (list
|| ex_count
) {
5160 MonoException
*exc
= NULL
;
5161 MonoArray
*exl
= NULL
;
5162 int j
, length
= g_list_length (list
) + ex_count
;
5164 mono_loader_clear_error ();
5166 exl
= mono_array_new (domain
, mono_defaults
.exception_class
, length
);
5167 /* Types for which mono_class_get () succeeded */
5168 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5169 MonoException
*exc
= mono_class_get_exception_for_failure (tmp
->data
);
5170 mono_array_setref (exl
, i
, exc
);
5172 /* Types for which it don't */
5173 for (j
= 0; j
< mono_array_length (exceptions
); ++j
) {
5174 MonoException
*exc
= mono_array_get (exceptions
, MonoException
*, j
);
5176 g_assert (i
< length
);
5177 mono_array_setref (exl
, i
, exc
);
5184 exc
= mono_get_exception_reflection_type_load (res
, exl
);
5185 mono_loader_clear_error ();
5186 mono_raise_exception (exc
);
5193 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName
*name
, MonoString
*assname
)
5195 MonoAssemblyName aname
;
5196 MonoDomain
*domain
= mono_object_domain (name
);
5198 gboolean is_version_defined
;
5199 gboolean is_token_defined
;
5201 aname
.public_key
= NULL
;
5202 val
= mono_string_to_utf8 (assname
);
5203 if (!mono_assembly_name_parse_full (val
, &aname
, TRUE
, &is_version_defined
, &is_token_defined
)) {
5204 g_free ((guint8
*) aname
.public_key
);
5209 fill_reflection_assembly_name (domain
, name
, &aname
, "", is_version_defined
,
5210 FALSE
, is_token_defined
);
5212 mono_assembly_name_free (&aname
);
5213 g_free ((guint8
*) aname
.public_key
);
5219 static MonoReflectionType
*
5220 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule
*module
)
5222 MonoDomain
*domain
= mono_object_domain (module
);
5225 MONO_ARCH_SAVE_REGS
;
5227 g_assert (module
->image
);
5229 if (module
->image
->dynamic
&& ((MonoDynamicImage
*)(module
->image
))->initial_image
)
5230 /* These images do not have a global type */
5233 klass
= mono_class_get (module
->image
, 1 | MONO_TOKEN_TYPE_DEF
);
5234 return mono_type_get_object (domain
, &klass
->byval_arg
);
5238 ves_icall_System_Reflection_Module_Close (MonoReflectionModule
*module
)
5240 /*if (module->image)
5241 mono_image_close (module->image);*/
5245 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule
*module
)
5247 MonoDomain
*domain
= mono_object_domain (module
);
5249 MONO_ARCH_SAVE_REGS
;
5251 g_assert (module
->image
);
5252 return mono_string_new (domain
, module
->image
->guid
);
5256 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule
*module
)
5259 if (module
->image
&& module
->image
->is_module_handle
)
5260 return module
->image
->raw_data
;
5263 return (gpointer
) (-1);
5267 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
)
5269 if (image
->dynamic
) {
5270 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5271 *pe_kind
= dyn
->pe_kind
;
5272 *machine
= dyn
->machine
;
5275 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5276 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5281 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
)
5283 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5287 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule
*module
)
5289 MonoArray
*exceptions
;
5292 MONO_ARCH_SAVE_REGS
;
5295 return mono_array_new (mono_object_domain (module
), mono_defaults
.monotype_class
, 0);
5297 MonoArray
*res
= mono_module_get_types (mono_object_domain (module
), module
->image
, &exceptions
, FALSE
);
5298 for (i
= 0; i
< mono_array_length (exceptions
); ++i
) {
5299 MonoException
*ex
= mono_array_get (exceptions
, MonoException
*, i
);
5301 mono_raise_exception (ex
);
5308 mono_metadata_memberref_is_method (MonoImage
*image
, guint32 token
)
5310 guint32 cols
[MONO_MEMBERREF_SIZE
];
5312 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5313 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5314 mono_metadata_decode_blob_size (sig
, &sig
);
5315 return (*sig
!= 0x6);
5319 init_generic_context_from_args (MonoGenericContext
*context
, MonoArray
*type_args
, MonoArray
*method_args
)
5322 context
->class_inst
= mono_metadata_get_generic_inst (mono_array_length (type_args
),
5323 mono_array_addr (type_args
, MonoType
*, 0));
5325 context
->class_inst
= NULL
;
5327 context
->method_inst
= mono_metadata_get_generic_inst (mono_array_length (method_args
),
5328 mono_array_addr (method_args
, MonoType
*, 0));
5330 context
->method_inst
= NULL
;
5334 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5337 int table
= mono_metadata_token_table (token
);
5338 int index
= mono_metadata_token_index (token
);
5339 MonoGenericContext context
;
5341 *error
= ResolveTokenError_Other
;
5343 /* Validate token */
5344 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5345 (table
!= MONO_TABLE_TYPESPEC
)) {
5346 *error
= ResolveTokenError_BadTable
;
5350 if (image
->dynamic
) {
5351 if (type_args
|| method_args
)
5352 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5353 klass
= mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5356 return &klass
->byval_arg
;
5359 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5360 *error
= ResolveTokenError_OutOfRange
;
5364 init_generic_context_from_args (&context
, type_args
, method_args
);
5365 klass
= mono_class_get_full (image
, token
, &context
);
5367 if (mono_loader_get_last_error ())
5368 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5371 return &klass
->byval_arg
;
5377 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5379 int table
= mono_metadata_token_table (token
);
5380 int index
= mono_metadata_token_index (token
);
5381 MonoGenericContext context
;
5384 *error
= ResolveTokenError_Other
;
5386 /* Validate token */
5387 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5388 (table
!= MONO_TABLE_MEMBERREF
)) {
5389 *error
= ResolveTokenError_BadTable
;
5393 if (image
->dynamic
) {
5394 if (type_args
|| method_args
)
5395 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5396 /* FIXME: validate memberref token type */
5397 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5400 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5401 *error
= ResolveTokenError_OutOfRange
;
5404 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_metadata_memberref_is_method (image
, token
))) {
5405 *error
= ResolveTokenError_BadTable
;
5409 init_generic_context_from_args (&context
, type_args
, method_args
);
5410 method
= mono_get_method_full (image
, token
, NULL
, &context
);
5412 if (mono_loader_get_last_error ())
5413 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5419 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5421 int index
= mono_metadata_token_index (token
);
5423 *error
= ResolveTokenError_Other
;
5425 /* Validate token */
5426 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5427 *error
= ResolveTokenError_BadTable
;
5432 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5434 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5435 *error
= ResolveTokenError_OutOfRange
;
5439 /* FIXME: What to do if the index points into the middle of a string ? */
5441 return mono_ldstr (mono_domain_get (), image
, index
);
5444 static MonoClassField
*
5445 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5448 int table
= mono_metadata_token_table (token
);
5449 int index
= mono_metadata_token_index (token
);
5450 MonoGenericContext context
;
5451 MonoClassField
*field
;
5453 *error
= ResolveTokenError_Other
;
5455 /* Validate token */
5456 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
5457 *error
= ResolveTokenError_BadTable
;
5461 if (image
->dynamic
) {
5462 if (type_args
|| method_args
)
5463 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5464 /* FIXME: validate memberref token type */
5465 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5468 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5469 *error
= ResolveTokenError_OutOfRange
;
5472 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_metadata_memberref_is_method (image
, token
))) {
5473 *error
= ResolveTokenError_BadTable
;
5477 init_generic_context_from_args (&context
, type_args
, method_args
);
5478 field
= mono_field_from_token (image
, token
, &klass
, &context
);
5480 if (mono_loader_get_last_error ())
5481 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5488 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5490 int table
= mono_metadata_token_table (token
);
5492 *error
= ResolveTokenError_Other
;
5495 case MONO_TABLE_TYPEDEF
:
5496 case MONO_TABLE_TYPEREF
:
5497 case MONO_TABLE_TYPESPEC
: {
5498 MonoType
*t
= ves_icall_System_Reflection_Module_ResolveTypeToken (image
, token
, type_args
, method_args
, error
);
5500 return (MonoObject
*)mono_type_get_object (mono_domain_get (), t
);
5504 case MONO_TABLE_METHOD
:
5505 case MONO_TABLE_METHODSPEC
: {
5506 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5508 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5512 case MONO_TABLE_FIELD
: {
5513 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5515 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5519 case MONO_TABLE_MEMBERREF
:
5520 if (mono_metadata_memberref_is_method (image
, token
)) {
5521 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5523 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5528 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5530 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5537 *error
= ResolveTokenError_BadTable
;
5544 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5546 int table
= mono_metadata_token_table (token
);
5547 int idx
= mono_metadata_token_index (token
);
5548 MonoTableInfo
*tables
= image
->tables
;
5553 *error
= ResolveTokenError_OutOfRange
;
5555 /* FIXME: Support other tables ? */
5556 if (table
!= MONO_TABLE_STANDALONESIG
)
5562 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
5565 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
5567 ptr
= mono_metadata_blob_heap (image
, sig
);
5568 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
5570 res
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, len
);
5571 memcpy (mono_array_addr (res
, guint8
, 0), ptr
, len
);
5575 static MonoReflectionType
*
5576 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder
*tb
, MonoString
*smodifiers
)
5579 int isbyref
= 0, rank
;
5580 char *str
= mono_string_to_utf8 (smodifiers
);
5583 MONO_ARCH_SAVE_REGS
;
5585 klass
= mono_class_from_mono_type (tb
->type
.type
);
5587 /* logic taken from mono_reflection_parse_type(): keep in sync */
5591 if (isbyref
) { /* only one level allowed by the spec */
5598 return mono_type_get_object (mono_object_domain (tb
), &klass
->this_arg
);
5601 klass
= mono_ptr_class_get (&klass
->byval_arg
);
5602 mono_class_init (klass
);
5613 else if (*p
!= '*') { /* '*' means unknown lower bound */
5624 klass
= mono_array_class_get (klass
, rank
);
5625 mono_class_init (klass
);
5632 return mono_type_get_object (mono_object_domain (tb
), &klass
->byval_arg
);
5636 ves_icall_Type_IsArrayImpl (MonoReflectionType
*t
)
5641 MONO_ARCH_SAVE_REGS
;
5644 res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
5649 static MonoReflectionType
*
5650 ves_icall_Type_make_array_type (MonoReflectionType
*type
, int rank
)
5652 MonoClass
*klass
, *aklass
;
5654 MONO_ARCH_SAVE_REGS
;
5656 klass
= mono_class_from_mono_type (type
->type
);
5657 if (rank
== 0) //single dimentional array
5658 aklass
= mono_array_class_get (klass
, 1);
5660 aklass
= mono_bounded_array_class_get (klass
, rank
, TRUE
);
5662 return mono_type_get_object (mono_object_domain (type
), &aklass
->byval_arg
);
5665 static MonoReflectionType
*
5666 ves_icall_Type_make_byref_type (MonoReflectionType
*type
)
5670 MONO_ARCH_SAVE_REGS
;
5672 klass
= mono_class_from_mono_type (type
->type
);
5674 return mono_type_get_object (mono_object_domain (type
), &klass
->this_arg
);
5677 static MonoReflectionType
*
5678 ves_icall_Type_MakePointerType (MonoReflectionType
*type
)
5682 MONO_ARCH_SAVE_REGS
;
5684 pklass
= mono_ptr_class_get (type
->type
);
5686 return mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
);
5690 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType
*type
, MonoObject
*target
,
5691 MonoReflectionMethod
*info
, MonoBoolean throwOnBindFailure
)
5693 MonoClass
*delegate_class
= mono_class_from_mono_type (type
->type
);
5694 MonoObject
*delegate
;
5696 MonoMethod
*method
= info
->method
;
5698 MONO_ARCH_SAVE_REGS
;
5700 mono_assert (delegate_class
->parent
== mono_defaults
.multicastdelegate_class
);
5702 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
) {
5703 if (!mono_security_core_clr_ensure_delegate_creation (method
, throwOnBindFailure
))
5707 delegate
= mono_object_new (mono_object_domain (type
), delegate_class
);
5709 if (method
->dynamic
) {
5710 /* Creating a trampoline would leak memory */
5711 func
= mono_compile_method (method
);
5713 func
= mono_create_ftnptr (mono_domain_get (),
5714 mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
));
5717 mono_delegate_ctor_with_method (delegate
, target
, func
, method
);
5723 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate
*this)
5725 /* Reset the invoke impl to the default one */
5726 this->invoke_impl
= mono_runtime_create_delegate_trampoline (this->object
.vtable
->klass
);
5730 * Magic number to convert a time which is relative to
5731 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5733 #define EPOCH_ADJUST ((guint64)62135596800LL)
5736 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5738 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5741 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5743 convert_to_absolute_date(SYSTEMTIME
*date
)
5745 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5746 static int days_in_month
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5747 static int leap_days_in_month
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5748 /* from the calendar FAQ */
5749 int a
= (14 - date
->wMonth
) / 12;
5750 int y
= date
->wYear
- a
;
5751 int m
= date
->wMonth
+ 12 * a
- 2;
5752 int d
= (1 + y
+ y
/4 - y
/100 + y
/400 + (31*m
)/12) % 7;
5754 /* d is now the day of the week for the first of the month (0 == Sunday) */
5756 int day_of_week
= date
->wDayOfWeek
;
5758 /* set day_in_month to the first day in the month which falls on day_of_week */
5759 int day_in_month
= 1 + (day_of_week
- d
);
5760 if (day_in_month
<= 0)
5763 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5764 date
->wDay
= day_in_month
+ (date
->wDay
- 1) * 7;
5765 if (date
->wDay
> (IS_LEAP(date
->wYear
) ? leap_days_in_month
[date
->wMonth
- 1] : days_in_month
[date
->wMonth
- 1]))
5772 * Return's the offset from GMT of a local time.
5774 * tm is a local time
5775 * t is the same local time as seconds.
5778 gmt_offset(struct tm
*tm
, time_t t
)
5780 #if defined (HAVE_TM_GMTOFF)
5781 return tm
->tm_gmtoff
;
5786 g
.tm_isdst
= tm
->tm_isdst
;
5788 return (int)difftime(t
, t2
);
5793 * This is heavily based on zdump.c from glibc 2.2.
5795 * * data[0]: start of daylight saving time (in DateTime ticks).
5796 * * data[1]: end of daylight saving time (in DateTime ticks).
5797 * * data[2]: utcoffset (in TimeSpan ticks).
5798 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5799 * * name[0]: name of this timezone when not daylight saving.
5800 * * name[1]: name of this timezone when daylight saving.
5802 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5803 * the class library allows years between 1 and 9999.
5805 * Returns true on success and zero on failure.
5808 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year
, MonoArray
**data
, MonoArray
**names
)
5811 MonoDomain
*domain
= mono_domain_get ();
5812 struct tm start
, tt
;
5816 int is_daylight
= 0, day
;
5819 MONO_ARCH_SAVE_REGS
;
5821 MONO_CHECK_ARG_NULL (data
);
5822 MONO_CHECK_ARG_NULL (names
);
5824 mono_gc_wbarrier_generic_store (data
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5825 mono_gc_wbarrier_generic_store (names
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.string_class
, 2));
5828 * no info is better than crashing: we'll need our own tz data
5829 * to make this work properly, anyway. The range is probably
5830 * reduced to 1970 .. 2037 because that is what mktime is
5831 * guaranteed to support (we get into an infinite loop
5835 memset (&start
, 0, sizeof (start
));
5838 start
.tm_year
= year
-1900;
5840 t
= mktime (&start
);
5842 if ((year
< 1970) || (year
> 2037) || (t
== -1)) {
5844 tt
= *localtime (&t
);
5845 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5846 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5847 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5851 gmtoff
= gmt_offset (&start
, t
);
5853 /* For each day of the year, calculate the tm_gmtoff. */
5854 for (day
= 0; day
< 365; day
++) {
5857 tt
= *localtime (&t
);
5859 /* Daylight saving starts or ends here. */
5860 if (gmt_offset (&tt
, t
) != gmtoff
) {
5864 /* Try to find the exact hour when daylight saving starts/ends. */
5868 tt1
= *localtime (&t1
);
5869 } while (gmt_offset (&tt1
, t1
) != gmtoff
);
5871 /* Try to find the exact minute when daylight saving starts/ends. */
5874 tt1
= *localtime (&t1
);
5875 } while (gmt_offset (&tt1
, t1
) == gmtoff
);
5877 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5879 /* Write data, if we're already in daylight saving, we're done. */
5881 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5882 mono_array_set ((*data
), gint64
, 1, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5885 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5886 mono_array_set ((*data
), gint64
, 0, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5890 /* This is only set once when we enter daylight saving. */
5891 mono_array_set ((*data
), gint64
, 2, (gint64
)gmtoff
* 10000000L);
5892 mono_array_set ((*data
), gint64
, 3, (gint64
)(gmt_offset (&tt
, t
) - gmtoff
) * 10000000L);
5894 gmtoff
= gmt_offset (&tt
, t
);
5899 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5900 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5901 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5902 mono_array_set ((*data
), gint64
, 0, 0);
5903 mono_array_set ((*data
), gint64
, 1, 0);
5904 mono_array_set ((*data
), gint64
, 2, (gint64
) gmtoff
* 10000000L);
5905 mono_array_set ((*data
), gint64
, 3, 0);
5910 MonoDomain
*domain
= mono_domain_get ();
5911 TIME_ZONE_INFORMATION tz_info
;
5916 tz_id
= GetTimeZoneInformation (&tz_info
);
5917 if (tz_id
== TIME_ZONE_ID_INVALID
)
5920 MONO_CHECK_ARG_NULL (data
);
5921 MONO_CHECK_ARG_NULL (names
);
5923 mono_gc_wbarrier_generic_store (data
, mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5924 mono_gc_wbarrier_generic_store (names
, mono_array_new (domain
, mono_defaults
.string_class
, 2));
5926 for (i
= 0; i
< 32; ++i
)
5927 if (!tz_info
.DaylightName
[i
])
5929 mono_array_setref ((*names
), 1, mono_string_new_utf16 (domain
, tz_info
.DaylightName
, i
));
5930 for (i
= 0; i
< 32; ++i
)
5931 if (!tz_info
.StandardName
[i
])
5933 mono_array_setref ((*names
), 0, mono_string_new_utf16 (domain
, tz_info
.StandardName
, i
));
5935 if ((year
<= 1601) || (year
> 30827)) {
5937 * According to MSDN, the MS time functions can't handle dates outside
5943 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5944 if (tz_id
!= TIME_ZONE_ID_UNKNOWN
) {
5945 tz_info
.StandardDate
.wYear
= year
;
5946 convert_to_absolute_date(&tz_info
.StandardDate
);
5947 err
= SystemTimeToFileTime (&tz_info
.StandardDate
, &ft
);
5952 mono_array_set ((*data
), gint64
, 1, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
5953 tz_info
.DaylightDate
.wYear
= year
;
5954 convert_to_absolute_date(&tz_info
.DaylightDate
);
5955 err
= SystemTimeToFileTime (&tz_info
.DaylightDate
, &ft
);
5960 mono_array_set ((*data
), gint64
, 0, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
5962 mono_array_set ((*data
), gint64
, 2, (tz_info
.Bias
+ tz_info
.StandardBias
) * -600000000LL);
5963 mono_array_set ((*data
), gint64
, 3, (tz_info
.DaylightBias
- tz_info
.StandardBias
) * -600000000LL);
5970 ves_icall_System_Object_obj_address (MonoObject
*this)
5972 MONO_ARCH_SAVE_REGS
;
5979 static inline gint32
5980 mono_array_get_byte_length (MonoArray
*array
)
5986 klass
= array
->obj
.vtable
->klass
;
5988 if (array
->bounds
== NULL
)
5989 length
= array
->max_length
;
5992 for (i
= 0; i
< klass
->rank
; ++ i
)
5993 length
*= array
->bounds
[i
].length
;
5996 switch (klass
->element_class
->byval_arg
.type
) {
5999 case MONO_TYPE_BOOLEAN
:
6003 case MONO_TYPE_CHAR
:
6011 return length
* sizeof (gpointer
);
6022 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6024 MONO_ARCH_SAVE_REGS
;
6026 return mono_array_get_byte_length (array
);
6030 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6032 MONO_ARCH_SAVE_REGS
;
6034 return mono_array_get (array
, gint8
, idx
);
6038 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6040 MONO_ARCH_SAVE_REGS
;
6042 mono_array_set (array
, gint8
, idx
, value
);
6046 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6048 guint8
*src_buf
, *dest_buf
;
6050 MONO_ARCH_SAVE_REGS
;
6052 /* watch out for integer overflow */
6053 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6056 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6057 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6060 memcpy (dest_buf
, src_buf
, count
);
6062 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6068 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject
*this, MonoString
*class_name
)
6070 MonoDomain
*domain
= mono_object_domain (this);
6072 MonoRealProxy
*rp
= ((MonoRealProxy
*)this);
6073 MonoTransparentProxy
*tp
;
6077 MONO_ARCH_SAVE_REGS
;
6079 res
= mono_object_new (domain
, mono_defaults
.transparent_proxy_class
);
6080 tp
= (MonoTransparentProxy
*) res
;
6082 MONO_OBJECT_SETREF (tp
, rp
, rp
);
6083 type
= ((MonoReflectionType
*)rp
->class_to_proxy
)->type
;
6084 klass
= mono_class_from_mono_type (type
);
6086 tp
->custom_type_info
= (mono_object_isinst (this, mono_defaults
.iremotingtypeinfo_class
) != NULL
);
6087 tp
->remote_class
= mono_remote_class (domain
, class_name
, klass
);
6089 res
->vtable
= mono_remote_class_vtable (domain
, tp
->remote_class
, rp
);
6093 static MonoReflectionType
*
6094 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6096 return mono_type_get_object (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
);
6099 /* System.Environment */
6102 ves_icall_System_Environment_get_UserName (void)
6104 MONO_ARCH_SAVE_REGS
;
6106 /* using glib is more portable */
6107 return mono_string_new (mono_domain_get (), g_get_user_name ());
6112 ves_icall_System_Environment_get_MachineName (void)
6114 #if defined (HOST_WIN32)
6119 len
= MAX_COMPUTERNAME_LENGTH
+ 1;
6120 buf
= g_new (gunichar2
, len
);
6123 if (GetComputerName (buf
, (PDWORD
) &len
))
6124 result
= mono_string_new_utf16 (mono_domain_get (), buf
, len
);
6128 #elif !defined(DISABLE_SOCKETS)
6132 if (gethostname (buf
, sizeof (buf
)) == 0)
6133 result
= mono_string_new (mono_domain_get (), buf
);
6139 return mono_string_new (mono_domain_get (), "mono");
6144 ves_icall_System_Environment_get_Platform (void)
6146 #if defined (TARGET_WIN32)
6149 #elif defined(__MACH__)
6152 // For compatibility with our client code, this will be 4 for a while.
6153 // We will eventually move to 6 to match .NET, but it requires all client
6154 // code to be updated and the documentation everywhere to be updated
6165 ves_icall_System_Environment_get_NewLine (void)
6167 MONO_ARCH_SAVE_REGS
;
6169 #if defined (HOST_WIN32)
6170 return mono_string_new (mono_domain_get (), "\r\n");
6172 return mono_string_new (mono_domain_get (), "\n");
6177 ves_icall_System_Environment_GetEnvironmentVariable (MonoString
*name
)
6182 MONO_ARCH_SAVE_REGS
;
6187 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6188 value
= g_getenv (utf8_name
);
6195 return mono_string_new (mono_domain_get (), value
);
6199 * There is no standard way to get at environ.
6202 #ifndef __MINGW32_VERSION
6204 /* Apple defines this in crt_externs.h but doesn't provide that header for
6205 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6206 * in fact exist on all implementations (so far)
6208 gchar
***_NSGetEnviron(void);
6209 #define environ (*_NSGetEnviron())
6218 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6229 env_strings
= GetEnvironmentStrings();
6232 env_string
= env_strings
;
6233 while (*env_string
!= '\0') {
6234 /* weird case that MS seems to skip */
6235 if (*env_string
!= '=')
6237 while (*env_string
!= '\0')
6243 domain
= mono_domain_get ();
6244 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6248 env_string
= env_strings
;
6249 while (*env_string
!= '\0') {
6250 /* weird case that MS seems to skip */
6251 if (*env_string
!= '=') {
6252 equal_str
= wcschr(env_string
, '=');
6253 g_assert(equal_str
);
6254 str
= mono_string_new_utf16 (domain
, env_string
, equal_str
-env_string
);
6255 mono_array_setref (names
, n
, str
);
6258 while (*env_string
!= '\0')
6263 FreeEnvironmentStrings (env_strings
);
6275 MONO_ARCH_SAVE_REGS
;
6278 for (e
= environ
; *e
!= 0; ++ e
)
6281 domain
= mono_domain_get ();
6282 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6285 for (e
= environ
; *e
!= 0; ++ e
) {
6286 parts
= g_strsplit (*e
, "=", 2);
6288 str
= mono_string_new (domain
, *parts
);
6289 mono_array_setref (names
, n
, str
);
6302 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6304 #if !GLIB_CHECK_VERSION(2,4,0)
6305 #define g_setenv(a,b,c) setenv(a,b,c)
6306 #define g_unsetenv(a) unsetenv(a)
6310 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6315 gunichar2
*utf16_name
, *utf16_value
;
6317 gchar
*utf8_name
, *utf8_value
;
6320 MONO_ARCH_SAVE_REGS
;
6323 utf16_name
= mono_string_to_utf16 (name
);
6324 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6325 SetEnvironmentVariable (utf16_name
, NULL
);
6326 g_free (utf16_name
);
6330 utf16_value
= mono_string_to_utf16 (value
);
6332 SetEnvironmentVariable (utf16_name
, utf16_value
);
6334 g_free (utf16_name
);
6335 g_free (utf16_value
);
6337 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6339 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6340 g_unsetenv (utf8_name
);
6345 utf8_value
= mono_string_to_utf8_checked (value
, &error
);
6346 if (!mono_error_ok (&error
)) {
6348 mono_error_raise_exception (&error
);
6350 g_setenv (utf8_name
, utf8_value
, TRUE
);
6353 g_free (utf8_value
);
6358 ves_icall_System_Environment_Exit (int result
)
6360 MONO_ARCH_SAVE_REGS
;
6362 mono_threads_set_shutting_down ();
6364 mono_runtime_set_shutting_down ();
6366 /* This will kill the tp threads which cannot be suspended */
6367 mono_thread_pool_cleanup ();
6369 /* Suspend all managed threads since the runtime is going away */
6370 mono_thread_suspend_all_other_threads ();
6372 mono_runtime_quit ();
6374 /* we may need to do some cleanup here... */
6379 ves_icall_System_Environment_GetGacPath (void)
6381 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6385 ves_icall_System_Environment_GetWindowsFolderPath (int folder
)
6387 #if defined (HOST_WIN32)
6388 #ifndef CSIDL_FLAG_CREATE
6389 #define CSIDL_FLAG_CREATE 0x8000
6392 WCHAR path
[MAX_PATH
];
6393 /* Create directory if no existing */
6394 if (SUCCEEDED (SHGetFolderPathW (NULL
, folder
| CSIDL_FLAG_CREATE
, NULL
, 0, path
))) {
6398 return mono_string_new_utf16 (mono_domain_get (), path
, len
);
6401 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6403 return mono_string_new (mono_domain_get (), "");
6407 ves_icall_System_Environment_GetLogicalDrives (void)
6409 gunichar2 buf
[128], *ptr
, *dname
;
6411 guint initial_size
= 127, size
= 128;
6414 MonoString
*drivestr
;
6415 MonoDomain
*domain
= mono_domain_get ();
6418 MONO_ARCH_SAVE_REGS
;
6423 while (size
> initial_size
) {
6424 size
= (guint
) GetLogicalDriveStrings (initial_size
, ptr
);
6425 if (size
> initial_size
) {
6428 ptr
= g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6429 initial_size
= size
;
6443 result
= mono_array_new (domain
, mono_defaults
.string_class
, ndrives
);
6448 while (*u16
) { u16
++; len
++; }
6449 drivestr
= mono_string_new_utf16 (domain
, dname
, len
);
6450 mono_array_setref (result
, ndrives
++, drivestr
);
6461 ves_icall_System_Environment_InternalGetHome (void)
6463 MONO_ARCH_SAVE_REGS
;
6465 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6468 static const char *encodings
[] = {
6470 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6471 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6472 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6474 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6475 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6476 "x_unicode_2_0_utf_7",
6478 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6479 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6481 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6484 "unicodefffe", "utf_16be",
6491 * Returns the internal codepage, if the value of "int_code_page" is
6492 * 1 at entry, and we can not compute a suitable code page number,
6493 * returns the code page as a string
6496 ves_icall_System_Text_Encoding_InternalCodePage (gint32
*int_code_page
)
6501 char *codepage
= NULL
;
6503 int want_name
= *int_code_page
;
6506 *int_code_page
= -1;
6507 MONO_ARCH_SAVE_REGS
;
6509 g_get_charset (&cset
);
6510 c
= codepage
= strdup (cset
);
6511 for (c
= codepage
; *c
; c
++){
6512 if (isascii (*c
) && isalpha (*c
))
6517 /* g_print ("charset: %s\n", cset); */
6519 /* handle some common aliases */
6522 for (i
= 0; p
!= 0; ){
6523 if ((gssize
) p
< 7){
6525 p
= encodings
[++i
];
6528 if (strcmp (p
, codepage
) == 0){
6529 *int_code_page
= code
;
6532 p
= encodings
[++i
];
6535 if (strstr (codepage
, "utf_8") != NULL
)
6536 *int_code_page
|= 0x10000000;
6539 if (want_name
&& *int_code_page
== -1)
6540 return mono_string_new (mono_domain_get (), cset
);
6546 ves_icall_System_Environment_get_HasShutdownStarted (void)
6548 if (mono_runtime_is_shutting_down ())
6551 if (mono_domain_is_unloading (mono_domain_get ()))
6558 ves_icall_System_Environment_BroadcastSettingChange (void)
6561 SendMessageTimeout (HWND_BROADCAST
, WM_SETTINGCHANGE
, NULL
, L
"Environment", SMTO_ABORTIFHUNG
, 2000, 0);
6566 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage
*this,
6567 MonoReflectionMethod
*method
,
6568 MonoArray
*out_args
)
6570 MONO_ARCH_SAVE_REGS
;
6572 mono_message_init (mono_object_domain (this), this, method
, out_args
);
6576 ves_icall_IsTransparentProxy (MonoObject
*proxy
)
6578 MONO_ARCH_SAVE_REGS
;
6583 if (proxy
->vtable
->klass
== mono_defaults
.transparent_proxy_class
)
6589 static MonoReflectionMethod
*
6590 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6591 MonoReflectionType
*rtype
, MonoReflectionMethod
*rmethod
)
6595 MonoMethod
**vtable
;
6596 MonoMethod
*res
= NULL
;
6598 MONO_CHECK_ARG_NULL (rtype
);
6599 MONO_CHECK_ARG_NULL (rmethod
);
6601 method
= rmethod
->method
;
6602 klass
= mono_class_from_mono_type (rtype
->type
);
6604 if (MONO_CLASS_IS_INTERFACE (klass
))
6607 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
6610 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
6611 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
6617 mono_class_setup_vtable (klass
);
6618 vtable
= klass
->vtable
;
6620 if (method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
) {
6621 gboolean variance_used
= FALSE
;
6622 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6623 int offs
= mono_class_interface_offset_with_variance (klass
, method
->klass
, &variance_used
);
6625 res
= vtable
[offs
+ method
->slot
];
6627 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
6630 if (method
->slot
!= -1)
6631 res
= vtable
[method
->slot
];
6637 return mono_method_get_object (mono_domain_get (), res
, NULL
);
6641 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType
*type
, MonoBoolean enable
)
6646 MONO_ARCH_SAVE_REGS
;
6648 klass
= mono_class_from_mono_type (type
->type
);
6649 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, TRUE
);
6651 if (enable
) vtable
->remote
= 1;
6652 else vtable
->remote
= 0;
6656 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType
*type
)
6661 MONO_ARCH_SAVE_REGS
;
6663 domain
= mono_object_domain (type
);
6664 klass
= mono_class_from_mono_type (type
->type
);
6666 if (klass
->rank
>= 1) {
6667 g_assert (klass
->rank
== 1);
6668 return (MonoObject
*) mono_array_new (domain
, klass
->element_class
, 0);
6670 /* Bypass remoting object creation check */
6671 return mono_object_new_alloc_specific (mono_class_vtable_full (domain
, klass
, TRUE
));
6676 ves_icall_System_IO_get_temp_path (void)
6678 MONO_ARCH_SAVE_REGS
;
6680 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6683 #ifndef PLATFORM_NO_DRIVEINFO
6685 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString
*path_name
, guint64
*free_bytes_avail
,
6686 guint64
*total_number_of_bytes
, guint64
*total_number_of_free_bytes
,
6690 ULARGE_INTEGER wapi_free_bytes_avail
;
6691 ULARGE_INTEGER wapi_total_number_of_bytes
;
6692 ULARGE_INTEGER wapi_total_number_of_free_bytes
;
6694 MONO_ARCH_SAVE_REGS
;
6696 *error
= ERROR_SUCCESS
;
6697 result
= GetDiskFreeSpaceEx (mono_string_chars (path_name
), &wapi_free_bytes_avail
, &wapi_total_number_of_bytes
,
6698 &wapi_total_number_of_free_bytes
);
6701 *free_bytes_avail
= wapi_free_bytes_avail
.QuadPart
;
6702 *total_number_of_bytes
= wapi_total_number_of_bytes
.QuadPart
;
6703 *total_number_of_free_bytes
= wapi_total_number_of_free_bytes
.QuadPart
;
6705 *free_bytes_avail
= 0;
6706 *total_number_of_bytes
= 0;
6707 *total_number_of_free_bytes
= 0;
6708 *error
= GetLastError ();
6715 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString
*root_path_name
)
6717 MONO_ARCH_SAVE_REGS
;
6719 return GetDriveType (mono_string_chars (root_path_name
));
6724 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod
*method
)
6726 MONO_ARCH_SAVE_REGS
;
6728 return mono_compile_method (method
);
6732 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6737 MONO_ARCH_SAVE_REGS
;
6739 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
6741 #if defined (HOST_WIN32)
6742 /* Avoid mixing '/' and '\\' */
6745 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6746 if (path
[i
] == '/')
6750 mcpath
= mono_string_new (mono_domain_get (), path
);
6757 get_bundled_machine_config (void)
6759 const gchar
*machine_config
;
6761 MONO_ARCH_SAVE_REGS
;
6763 machine_config
= mono_get_machine_config ();
6765 if (!machine_config
)
6768 return mono_string_new (mono_domain_get (), machine_config
);
6772 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6777 MONO_ARCH_SAVE_REGS
;
6779 path
= g_path_get_dirname (mono_get_config_dir ());
6781 #if defined (HOST_WIN32)
6782 /* Avoid mixing '/' and '\\' */
6785 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6786 if (path
[i
] == '/')
6790 ipath
= mono_string_new (mono_domain_get (), path
);
6797 ves_icall_get_resources_ptr (MonoReflectionAssembly
*assembly
, gpointer
*result
, gint32
*size
)
6799 MonoPEResourceDataEntry
*entry
;
6802 MONO_ARCH_SAVE_REGS
;
6804 if (!assembly
|| !result
|| !size
)
6809 image
= assembly
->assembly
->image
;
6810 entry
= mono_image_lookup_resource (image
, MONO_PE_RESOURCE_ID_ASPNET_STRING
, 0, NULL
);
6814 *result
= mono_image_rva_map (image
, entry
->rde_data_offset
);
6819 *size
= entry
->rde_size
;
6825 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
6827 return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
6831 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
6833 #if defined (HOST_WIN32)
6834 OutputDebugString (mono_string_chars (message
));
6836 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
6840 /* Only used for value types */
6842 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType
*type
)
6847 MONO_ARCH_SAVE_REGS
;
6849 domain
= mono_object_domain (type
);
6850 klass
= mono_class_from_mono_type (type
->type
);
6852 if (mono_class_is_nullable (klass
))
6853 /* No arguments -> null */
6856 return mono_object_new (domain
, klass
);
6859 static MonoReflectionMethod
*
6860 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod
*m
, gboolean definition
)
6862 MonoClass
*klass
, *parent
;
6863 MonoMethod
*method
= m
->method
;
6864 MonoMethod
*result
= NULL
;
6866 MONO_ARCH_SAVE_REGS
;
6868 if (method
->klass
== NULL
)
6871 if (!(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
) ||
6872 MONO_CLASS_IS_INTERFACE (method
->klass
) ||
6873 method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
)
6876 klass
= method
->klass
;
6877 if (klass
->generic_class
)
6878 klass
= klass
->generic_class
->container_class
;
6881 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6882 for (parent
= klass
->parent
; parent
!= NULL
; parent
= parent
->parent
) {
6883 mono_class_setup_vtable (parent
);
6884 if (parent
->vtable_size
<= method
->slot
)
6889 klass
= klass
->parent
;
6894 if (klass
== method
->klass
)
6897 result
= klass
->vtable
[method
->slot
];
6898 if (result
== NULL
) {
6899 /* It is an abstract method */
6900 gpointer iter
= NULL
;
6901 while ((result
= mono_class_get_methods (klass
, &iter
)))
6902 if (result
->slot
== method
->slot
)
6909 return mono_method_get_object (mono_domain_get (), result
, NULL
);
6913 ves_icall_MonoMethod_get_name (MonoReflectionMethod
*m
)
6915 MonoMethod
*method
= m
->method
;
6917 MONO_OBJECT_SETREF (m
, name
, mono_string_new (mono_object_domain (m
), method
->name
));
6922 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
6924 MONO_ARCH_SAVE_REGS
;
6926 iter
->sig
= *(MonoMethodSignature
**)argsp
;
6928 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
6929 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
6932 /* FIXME: it's not documented what start is exactly... */
6936 iter
->args
= argsp
+ sizeof (gpointer
);
6938 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
6940 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6944 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
6946 guint32 i
, arg_size
;
6949 MONO_ARCH_SAVE_REGS
;
6951 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
6953 g_assert (i
< iter
->sig
->param_count
);
6955 res
.type
= iter
->sig
->params
[i
];
6956 res
.klass
= mono_class_from_mono_type (res
.type
);
6957 res
.value
= iter
->args
;
6958 arg_size
= mono_type_stack_size (res
.type
, &align
);
6959 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
6960 if (arg_size
<= sizeof (gpointer
)) {
6962 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
6963 res
.value
= (guint8
*)res
.value
+ padding
;
6966 iter
->args
= (char*)iter
->args
+ arg_size
;
6969 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6975 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
6977 guint32 i
, arg_size
;
6980 MONO_ARCH_SAVE_REGS
;
6982 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
6984 g_assert (i
< iter
->sig
->param_count
);
6986 while (i
< iter
->sig
->param_count
) {
6987 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
6989 res
.type
= iter
->sig
->params
[i
];
6990 res
.klass
= mono_class_from_mono_type (res
.type
);
6991 /* FIXME: endianess issue... */
6992 res
.value
= iter
->args
;
6993 arg_size
= mono_type_stack_size (res
.type
, &align
);
6994 iter
->args
= (char*)iter
->args
+ arg_size
;
6996 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6999 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7008 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7011 MONO_ARCH_SAVE_REGS
;
7013 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7015 g_assert (i
< iter
->sig
->param_count
);
7017 return iter
->sig
->params
[i
];
7021 mono_TypedReference_ToObject (MonoTypedRef tref
)
7023 MONO_ARCH_SAVE_REGS
;
7025 if (MONO_TYPE_IS_REFERENCE (tref
.type
)) {
7026 MonoObject
** objp
= tref
.value
;
7030 return mono_value_box (mono_domain_get (), tref
.klass
, tref
.value
);
7034 mono_TypedReference_ToObjectInternal (MonoType
*type
, gpointer value
, MonoClass
*klass
)
7036 MONO_ARCH_SAVE_REGS
;
7038 if (MONO_TYPE_IS_REFERENCE (type
)) {
7039 MonoObject
** objp
= value
;
7043 return mono_value_box (mono_domain_get (), klass
, value
);
7047 prelink_method (MonoMethod
*method
)
7049 const char *exc_class
, *exc_arg
;
7050 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7052 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7054 mono_raise_exception(
7055 mono_exception_from_name_msg (mono_defaults
.corlib
, "System", exc_class
, exc_arg
) );
7057 /* create the wrapper, too? */
7061 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod
*method
)
7063 MONO_ARCH_SAVE_REGS
;
7064 prelink_method (method
->method
);
7068 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
*type
)
7070 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
7072 gpointer iter
= NULL
;
7073 MONO_ARCH_SAVE_REGS
;
7075 while ((m
= mono_class_get_methods (klass
, &iter
)))
7079 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7081 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7082 gint32
const **exponents
,
7083 gunichar2
const **digitLowerTable
,
7084 gunichar2
const **digitUpperTable
,
7085 gint64
const **tenPowersList
,
7086 gint32
const **decHexDigits
)
7088 *mantissas
= Formatter_MantissaBitsTable
;
7089 *exponents
= Formatter_TensExponentTable
;
7090 *digitLowerTable
= Formatter_DigitLowerTable
;
7091 *digitUpperTable
= Formatter_DigitUpperTable
;
7092 *tenPowersList
= Formatter_TenPowersList
;
7093 *decHexDigits
= Formatter_DecHexDigits
;
7096 /* These parameters are "readonly" in corlib/System/Char.cs */
7098 ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data
,
7099 guint8
const **numeric_data
,
7100 gdouble
const **numeric_data_values
,
7101 guint16
const **to_lower_data_low
,
7102 guint16
const **to_lower_data_high
,
7103 guint16
const **to_upper_data_low
,
7104 guint16
const **to_upper_data_high
)
7106 *category_data
= CategoryData
;
7107 *numeric_data
= NumericData
;
7108 *numeric_data_values
= NumericDataValues
;
7109 *to_lower_data_low
= ToLowerDataLow
;
7110 *to_lower_data_high
= ToLowerDataHigh
;
7111 *to_upper_data_low
= ToUpperDataLow
;
7112 *to_upper_data_high
= ToUpperDataHigh
;
7116 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod
*method
)
7118 return method
->method
->token
;
7122 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7123 * and avoid useless allocations.
7126 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
)
7130 for (i
= 0; i
< type
->num_mods
; ++i
) {
7131 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7136 res
= mono_array_new (mono_domain_get (), mono_defaults
.systemtype_class
, count
);
7138 for (i
= 0; i
< type
->num_mods
; ++i
) {
7139 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7140 MonoClass
*klass
= mono_class_get (image
, type
->modifiers
[i
].token
);
7141 mono_array_setref (res
, count
, mono_type_get_object (mono_domain_get (), &klass
->byval_arg
));
7149 param_info_get_type_modifiers (MonoReflectionParameter
*param
, MonoBoolean optional
)
7151 MonoType
*type
= param
->ClassImpl
->type
;
7152 MonoClass
*member_class
= mono_object_class (param
->MemberImpl
);
7153 MonoMethod
*method
= NULL
;
7156 MonoMethodSignature
*sig
;
7158 if (mono_class_is_reflection_method_or_constructor (member_class
)) {
7159 MonoReflectionMethod
*rmethod
= (MonoReflectionMethod
*)param
->MemberImpl
;
7160 method
= rmethod
->method
;
7161 } else if (member_class
->image
== mono_defaults
.corlib
&& !strcmp ("MonoProperty", member_class
->name
)) {
7162 MonoReflectionProperty
*prop
= (MonoReflectionProperty
*)param
->MemberImpl
;
7163 if (!(method
= prop
->property
->get
))
7164 method
= prop
->property
->set
;
7167 char *type_name
= mono_type_get_full_name (member_class
);
7168 char *msg
= g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name
);
7169 MonoException
*ex
= mono_get_exception_not_supported (msg
);
7172 mono_raise_exception (ex
);
7175 image
= method
->klass
->image
;
7176 pos
= param
->PositionImpl
;
7177 sig
= mono_method_signature (method
);
7181 type
= sig
->params
[pos
];
7183 return type_array_from_modifiers (image
, type
, optional
);
7187 get_property_type (MonoProperty
*prop
)
7189 MonoMethodSignature
*sig
;
7191 sig
= mono_method_signature (prop
->get
);
7193 } else if (prop
->set
) {
7194 sig
= mono_method_signature (prop
->set
);
7195 return sig
->params
[sig
->param_count
- 1];
7201 property_info_get_type_modifiers (MonoReflectionProperty
*property
, MonoBoolean optional
)
7203 MonoType
*type
= get_property_type (property
->property
);
7204 MonoImage
*image
= property
->klass
->image
;
7208 return type_array_from_modifiers (image
, type
, optional
);
7212 *Construct a MonoType suited to be used to decode a constant blob object.
7214 * @type is the target type which will be constructed
7215 * @blob_type is the blob type, for example, that comes from the constant table
7216 * @real_type is the expected constructed type.
7219 mono_type_from_blob_type (MonoType
*type
, MonoTypeEnum blob_type
, MonoType
*real_type
)
7221 type
->type
= blob_type
;
7222 type
->data
.klass
= NULL
;
7223 if (blob_type
== MONO_TYPE_CLASS
)
7224 type
->data
.klass
= mono_defaults
.object_class
;
7225 else if (real_type
->type
== MONO_TYPE_VALUETYPE
&& real_type
->data
.klass
->enumtype
) {
7226 /* For enums, we need to use the base type */
7227 type
->type
= MONO_TYPE_VALUETYPE
;
7228 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7230 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7234 property_info_get_default_value (MonoReflectionProperty
*property
)
7237 MonoProperty
*prop
= property
->property
;
7238 MonoType
*type
= get_property_type (prop
);
7239 MonoDomain
*domain
= mono_object_domain (property
);
7240 MonoTypeEnum def_type
;
7241 const char *def_value
;
7244 g_assert (!prop
->parent
->image
->dynamic
);
7246 mono_class_init (prop
->parent
);
7248 if (!(prop
->attrs
& PROPERTY_ATTRIBUTE_HAS_DEFAULT
))
7249 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
7251 def_value
= mono_class_get_property_default_value (prop
, &def_type
);
7253 mono_type_from_blob_type (&blob_type
, def_type
, type
);
7254 o
= mono_get_object_from_blob (domain
, &blob_type
, def_value
);
7260 custom_attrs_defined_internal (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7262 MonoCustomAttrInfo
*cinfo
;
7265 cinfo
= mono_reflection_get_custom_attrs_info (obj
);
7268 found
= mono_custom_attrs_has_attr (cinfo
, mono_class_from_mono_type (attr_type
->type
));
7270 mono_custom_attrs_free (cinfo
);
7275 custom_attrs_get_by_type (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7277 MonoArray
*res
= mono_reflection_get_custom_attrs_by_type (obj
, attr_type
? mono_class_from_mono_type (attr_type
->type
) : NULL
);
7279 if (mono_loader_get_last_error ()) {
7280 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7281 g_assert_not_reached ();
7290 ves_icall_Mono_Runtime_GetDisplayName (void)
7293 MonoString
*display_name
;
7295 info
= mono_get_runtime_callbacks ()->get_runtime_build_info ();
7296 display_name
= mono_string_new (mono_domain_get (), info
);
7298 return display_name
;
7302 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code
)
7304 MonoString
*message
;
7308 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
7309 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, code
, 0,
7312 message
= mono_string_new (mono_domain_get (), "Error looking up error string");
7314 message
= mono_string_new_utf16 (mono_domain_get (), buf
, ret
);
7322 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7323 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7324 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7325 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7326 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7327 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7328 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7329 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7333 base64_to_byte_array (gunichar2
*start
, gint ilength
, MonoBoolean allowWhitespaceOnly
)
7338 gunichar2 last
, prev_last
, prev2_last
;
7346 last
= prev_last
= 0, prev2_last
= 0;
7347 for (i
= 0; i
< ilength
; i
++) {
7349 if (c
>= sizeof (dbase64
)) {
7350 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7351 "System", "FormatException",
7352 "Invalid character found.");
7353 mono_raise_exception (exc
);
7354 } else if (isspace (c
)) {
7357 prev2_last
= prev_last
;
7363 olength
= ilength
- ignored
;
7365 if (allowWhitespaceOnly
&& olength
== 0) {
7366 return mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, 0);
7369 if ((olength
& 3) != 0 || olength
<= 0) {
7370 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System",
7371 "FormatException", "Invalid length.");
7372 mono_raise_exception (exc
);
7375 if (prev2_last
== '=') {
7376 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7377 mono_raise_exception (exc
);
7380 olength
= (olength
* 3) / 4;
7384 if (prev_last
== '=')
7387 result
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, olength
);
7388 res_ptr
= mono_array_addr (result
, guchar
, 0);
7389 for (i
= 0; i
< ilength
; ) {
7392 for (k
= 0; k
< 4 && i
< ilength
;) {
7398 if (((b
[k
] = dbase64
[c
]) & 0x80) != 0) {
7399 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7400 "System", "FormatException",
7401 "Invalid character found.");
7402 mono_raise_exception (exc
);
7407 *res_ptr
++ = (b
[0] << 2) | (b
[1] >> 4);
7409 *res_ptr
++ = (b
[1] << 4) | (b
[2] >> 2);
7411 *res_ptr
++ = (b
[2] << 6) | b
[3];
7413 while (i
< ilength
&& isspace (start
[i
]))
7421 InternalFromBase64String (MonoString
*str
, MonoBoolean allowWhitespaceOnly
)
7423 MONO_ARCH_SAVE_REGS
;
7425 return base64_to_byte_array (mono_string_chars (str
),
7426 mono_string_length (str
), allowWhitespaceOnly
);
7430 InternalFromBase64CharArray (MonoArray
*input
, gint offset
, gint length
)
7432 MONO_ARCH_SAVE_REGS
;
7434 return base64_to_byte_array (mono_array_addr (input
, gunichar2
, offset
),
7438 #define ICALL_TYPE(id,name,first)
7439 #define ICALL(id,name,func) Icall_ ## id,
7442 #include "metadata/icall-def.h"
7448 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7449 #define ICALL(id,name,func)
7451 #include "metadata/icall-def.h"
7457 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7458 #define ICALL(id,name,func)
7460 guint16 first_icall
;
7463 static const IcallTypeDesc
7464 icall_type_descs
[] = {
7465 #include "metadata/icall-def.h"
7469 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7472 #define ICALL_TYPE(id,name,first)
7475 #ifdef HAVE_ARRAY_ELEM_INIT
7476 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7477 #define MSGSTRFIELD1(line) str##line
7479 static const struct msgstrtn_t
{
7480 #define ICALL(id,name,func)
7482 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7483 #include "metadata/icall-def.h"
7485 } icall_type_names_str
= {
7486 #define ICALL_TYPE(id,name,first) (name),
7487 #include "metadata/icall-def.h"
7490 static const guint16 icall_type_names_idx
[] = {
7491 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7492 #include "metadata/icall-def.h"
7495 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7497 static const struct msgstr_t
{
7499 #define ICALL_TYPE(id,name,first)
7500 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7501 #include "metadata/icall-def.h"
7503 } icall_names_str
= {
7504 #define ICALL(id,name,func) (name),
7505 #include "metadata/icall-def.h"
7508 static const guint16 icall_names_idx
[] = {
7509 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7510 #include "metadata/icall-def.h"
7513 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7519 #define ICALL_TYPE(id,name,first) name,
7520 #define ICALL(id,name,func)
7521 static const char* const
7522 icall_type_names
[] = {
7523 #include "metadata/icall-def.h"
7527 #define icall_type_name_get(id) (icall_type_names [(id)])
7531 #define ICALL_TYPE(id,name,first)
7532 #define ICALL(id,name,func) name,
7533 static const char* const
7535 #include "metadata/icall-def.h"
7538 #define icall_name_get(id) icall_names [(id)]
7540 #endif /* !HAVE_ARRAY_ELEM_INIT */
7544 #define ICALL_TYPE(id,name,first)
7545 #define ICALL(id,name,func) func,
7546 static const gconstpointer
7547 icall_functions
[] = {
7548 #include "metadata/icall-def.h"
7552 static GHashTable
*icall_hash
= NULL
;
7553 static GHashTable
*jit_icall_hash_name
= NULL
;
7554 static GHashTable
*jit_icall_hash_addr
= NULL
;
7557 mono_icall_init (void)
7561 /* check that tables are sorted: disable in release */
7564 const char *prev_class
= NULL
;
7565 const char *prev_method
;
7567 for (i
= 0; i
< Icall_type_num
; ++i
) {
7568 const IcallTypeDesc
*desc
;
7571 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
7572 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
7573 prev_class
= icall_type_name_get (i
);
7574 desc
= &icall_type_descs
[i
];
7575 num_icalls
= icall_desc_num_icalls (desc
);
7576 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7577 for (j
= 0; j
< num_icalls
; ++j
) {
7578 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
7579 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
7580 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
7581 prev_method
= methodn
;
7586 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
7590 mono_icall_cleanup (void)
7592 g_hash_table_destroy (icall_hash
);
7593 g_hash_table_destroy (jit_icall_hash_name
);
7594 g_hash_table_destroy (jit_icall_hash_addr
);
7598 mono_add_internal_call (const char *name
, gconstpointer method
)
7600 mono_loader_lock ();
7602 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
7604 mono_loader_unlock ();
7607 #ifdef HAVE_ARRAY_ELEM_INIT
7609 compare_method_imap (const void *key
, const void *elem
)
7611 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
7612 return strcmp (key
, method_name
);
7616 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7618 const guint16
*nameslot
= bsearch (name
, icall_names_idx
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names_idx
[0]), compare_method_imap
);
7621 return (gpointer
)icall_functions
[(nameslot
- &icall_names_idx
[0])];
7625 compare_class_imap (const void *key
, const void *elem
)
7627 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
7628 return strcmp (key
, class_name
);
7631 static const IcallTypeDesc
*
7632 find_class_icalls (const char *name
)
7634 const guint16
*nameslot
= bsearch (name
, icall_type_names_idx
, Icall_type_num
, sizeof (icall_type_names_idx
[0]), compare_class_imap
);
7637 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
7642 compare_method_imap (const void *key
, const void *elem
)
7644 const char** method_name
= (const char**)elem
;
7645 return strcmp (key
, *method_name
);
7649 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7651 const char **nameslot
= bsearch (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
7654 return (gpointer
)icall_functions
[(nameslot
- icall_names
)];
7658 compare_class_imap (const void *key
, const void *elem
)
7660 const char** class_name
= (const char**)elem
;
7661 return strcmp (key
, *class_name
);
7664 static const IcallTypeDesc
*
7665 find_class_icalls (const char *name
)
7667 const char **nameslot
= bsearch (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
7670 return &icall_type_descs
[nameslot
- icall_type_names
];
7676 * we should probably export this as an helper (handle nested types).
7677 * Returns the number of chars written in buf.
7680 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
7682 int nspacelen
, cnamelen
;
7683 nspacelen
= strlen (klass
->name_space
);
7684 cnamelen
= strlen (klass
->name
);
7685 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
7688 memcpy (buf
, klass
->name_space
, nspacelen
);
7689 buf
[nspacelen
++] = '.';
7691 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
7692 buf
[nspacelen
+ cnamelen
] = 0;
7693 return nspacelen
+ cnamelen
;
7697 mono_lookup_internal_call (MonoMethod
*method
)
7702 int typelen
= 0, mlen
, siglen
;
7704 const IcallTypeDesc
*imap
;
7706 g_assert (method
!= NULL
);
7708 if (method
->is_inflated
)
7709 method
= ((MonoMethodInflated
*) method
)->declaring
;
7711 if (method
->klass
->nested_in
) {
7712 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
7716 mname
[pos
++] = '/';
7719 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
7725 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
7730 imap
= find_class_icalls (mname
);
7732 mname
[typelen
] = ':';
7733 mname
[typelen
+ 1] = ':';
7735 mlen
= strlen (method
->name
);
7736 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
7737 sigstart
= mname
+ typelen
+ 2 + mlen
;
7740 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
7741 siglen
= strlen (tmpsig
);
7742 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
7745 memcpy (sigstart
+ 1, tmpsig
, siglen
);
7746 sigstart
[siglen
+ 1] = ')';
7747 sigstart
[siglen
+ 2] = 0;
7750 mono_loader_lock ();
7752 res
= g_hash_table_lookup (icall_hash
, mname
);
7754 mono_loader_unlock ();
7757 /* try without signature */
7759 res
= g_hash_table_lookup (icall_hash
, mname
);
7761 mono_loader_unlock ();
7765 /* it wasn't found in the static call tables */
7767 mono_loader_unlock ();
7770 res
= find_method_icall (imap
, sigstart
- mlen
);
7772 mono_loader_unlock ();
7775 /* try _with_ signature */
7777 res
= find_method_icall (imap
, sigstart
- mlen
);
7779 mono_loader_unlock ();
7783 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
7784 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7785 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
7786 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7787 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");
7788 g_print ("If you see other errors or faults after this message they are probably related\n");
7789 g_print ("and you need to fix your mono install first.\n");
7791 mono_loader_unlock ();
7797 type_from_typename (char *typename
)
7799 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
7801 if (!strcmp (typename
, "int"))
7802 klass
= mono_defaults
.int_class
;
7803 else if (!strcmp (typename
, "ptr"))
7804 klass
= mono_defaults
.int_class
;
7805 else if (!strcmp (typename
, "void"))
7806 klass
= mono_defaults
.void_class
;
7807 else if (!strcmp (typename
, "int32"))
7808 klass
= mono_defaults
.int32_class
;
7809 else if (!strcmp (typename
, "uint32"))
7810 klass
= mono_defaults
.uint32_class
;
7811 else if (!strcmp (typename
, "int8"))
7812 klass
= mono_defaults
.sbyte_class
;
7813 else if (!strcmp (typename
, "uint8"))
7814 klass
= mono_defaults
.byte_class
;
7815 else if (!strcmp (typename
, "int16"))
7816 klass
= mono_defaults
.int16_class
;
7817 else if (!strcmp (typename
, "uint16"))
7818 klass
= mono_defaults
.uint16_class
;
7819 else if (!strcmp (typename
, "long"))
7820 klass
= mono_defaults
.int64_class
;
7821 else if (!strcmp (typename
, "ulong"))
7822 klass
= mono_defaults
.uint64_class
;
7823 else if (!strcmp (typename
, "float"))
7824 klass
= mono_defaults
.single_class
;
7825 else if (!strcmp (typename
, "double"))
7826 klass
= mono_defaults
.double_class
;
7827 else if (!strcmp (typename
, "object"))
7828 klass
= mono_defaults
.object_class
;
7829 else if (!strcmp (typename
, "obj"))
7830 klass
= mono_defaults
.object_class
;
7831 else if (!strcmp (typename
, "string"))
7832 klass
= mono_defaults
.string_class
;
7833 else if (!strcmp (typename
, "bool"))
7834 klass
= mono_defaults
.boolean_class
;
7835 else if (!strcmp (typename
, "boolean"))
7836 klass
= mono_defaults
.boolean_class
;
7838 g_error ("%s", typename
);
7839 g_assert_not_reached ();
7841 return &klass
->byval_arg
;
7844 MonoMethodSignature
*
7845 mono_create_icall_signature (const char *sigstr
)
7850 MonoMethodSignature
*res
;
7852 mono_loader_lock ();
7853 res
= g_hash_table_lookup (mono_defaults
.corlib
->helper_signatures
, sigstr
);
7855 mono_loader_unlock ();
7859 parts
= g_strsplit (sigstr
, " ", 256);
7868 res
= mono_metadata_signature_alloc (mono_defaults
.corlib
, len
- 1);
7873 * Under windows, the default pinvoke calling convention is STDCALL but
7876 res
->call_convention
= MONO_CALL_C
;
7879 res
->ret
= type_from_typename (parts
[0]);
7880 for (i
= 1; i
< len
; ++i
) {
7881 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
7886 g_hash_table_insert (mono_defaults
.corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
7888 mono_loader_unlock ();
7894 mono_find_jit_icall_by_name (const char *name
)
7896 MonoJitICallInfo
*info
;
7897 g_assert (jit_icall_hash_name
);
7899 mono_loader_lock ();
7900 info
= g_hash_table_lookup (jit_icall_hash_name
, name
);
7901 mono_loader_unlock ();
7906 mono_find_jit_icall_by_addr (gconstpointer addr
)
7908 MonoJitICallInfo
*info
;
7909 g_assert (jit_icall_hash_addr
);
7911 mono_loader_lock ();
7912 info
= g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
7913 mono_loader_unlock ();
7919 * mono_get_jit_icall_info:
7921 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7922 * caller should access it while holding the loader lock.
7925 mono_get_jit_icall_info (void)
7927 return jit_icall_hash_name
;
7931 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
7933 mono_loader_lock ();
7934 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
7935 mono_loader_unlock ();
7939 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
7941 MonoJitICallInfo
*info
;
7946 mono_loader_lock ();
7948 if (!jit_icall_hash_name
) {
7949 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
7950 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
7953 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
7954 g_warning ("jit icall already defined \"%s\"\n", name
);
7955 g_assert_not_reached ();
7958 info
= g_new0 (MonoJitICallInfo
, 1);
7965 info
->wrapper
= func
;
7967 info
->wrapper
= NULL
;
7970 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
7971 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
7973 mono_loader_unlock ();