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
)) {
2714 if (!mono_object_isinst (this, m
->klass
)) {
2715 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Object does not match target type."));
2718 m
= mono_object_get_virtual_method (this, m
);
2719 /* must pass the pointer to the value for valuetype methods */
2720 if (m
->klass
->valuetype
)
2721 obj
= mono_object_unbox (this);
2722 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
2723 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target."));
2728 pcount
= params
? mono_array_length (params
): 0;
2729 if (pcount
!= mono_method_signature (m
)->param_count
) {
2730 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException"));
2734 if ((m
->klass
->flags
& TYPE_ATTRIBUTE_ABSTRACT
) && !strcmp (m
->name
, ".ctor") && !this) {
2735 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."));
2739 if (m
->klass
->image
->assembly
->ref_only
) {
2740 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."));
2744 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
2747 intptr_t *lower_bounds
;
2748 pcount
= mono_array_length (params
);
2749 lengths
= alloca (sizeof (uintptr_t) * pcount
);
2750 /* Note: the synthetized array .ctors have int32 as argument type */
2751 for (i
= 0; i
< pcount
; ++i
)
2752 lengths
[i
] = *(int32_t*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
2754 if (m
->klass
->rank
== pcount
) {
2755 /* Only lengths provided. */
2756 lower_bounds
= NULL
;
2758 g_assert (pcount
== (m
->klass
->rank
* 2));
2759 /* lower bounds are first. */
2760 lower_bounds
= (intptr_t*)lengths
;
2761 lengths
+= m
->klass
->rank
;
2764 return (MonoObject
*)mono_array_new_full (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
);
2766 return mono_runtime_invoke_array (m
, obj
, params
, NULL
);
2770 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoArray
**outArgs
)
2772 MonoDomain
*domain
= mono_object_domain (method
);
2773 MonoMethod
*m
= method
->method
;
2774 MonoMethodSignature
*sig
= mono_method_signature (m
);
2775 MonoArray
*out_args
;
2777 int i
, j
, outarg_count
= 0;
2779 MONO_ARCH_SAVE_REGS
;
2781 if (m
->klass
== mono_defaults
.object_class
) {
2783 if (!strcmp (m
->name
, "FieldGetter")) {
2784 MonoClass
*k
= this->vtable
->klass
;
2788 /* If this is a proxy, then it must be a CBO */
2789 if (k
== mono_defaults
.transparent_proxy_class
) {
2790 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2791 this = tp
->rp
->unwrapped_server
;
2793 k
= this->vtable
->klass
;
2796 name
= mono_array_get (params
, MonoString
*, 1);
2797 str
= mono_string_to_utf8 (name
);
2800 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2802 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2803 if (field_klass
->valuetype
)
2804 result
= mono_value_box (domain
, field_klass
, (char *)this + field
->offset
);
2806 result
= *((gpointer
*)((char *)this + field
->offset
));
2808 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 1);
2809 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2810 mono_array_setref (out_args
, 0, result
);
2818 g_assert_not_reached ();
2820 } else if (!strcmp (m
->name
, "FieldSetter")) {
2821 MonoClass
*k
= this->vtable
->klass
;
2827 /* If this is a proxy, then it must be a CBO */
2828 if (k
== mono_defaults
.transparent_proxy_class
) {
2829 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2830 this = tp
->rp
->unwrapped_server
;
2832 k
= this->vtable
->klass
;
2835 name
= mono_array_get (params
, MonoString
*, 1);
2836 str
= mono_string_to_utf8 (name
);
2839 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2841 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2842 MonoObject
*val
= mono_array_get (params
, gpointer
, 2);
2844 if (field_klass
->valuetype
) {
2845 size
= mono_type_size (field
->type
, &align
);
2846 g_assert (size
== mono_class_value_size (field_klass
, NULL
));
2847 mono_gc_wbarrier_value_copy ((char *)this + field
->offset
, (char*)val
+ sizeof (MonoObject
), 1, field_klass
);
2849 mono_gc_wbarrier_set_field (this, (char*)this + field
->offset
, val
);
2852 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 0);
2853 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2863 g_assert_not_reached ();
2868 for (i
= 0; i
< mono_array_length (params
); i
++) {
2869 if (sig
->params
[i
]->byref
)
2873 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, outarg_count
);
2875 /* handle constructors only for objects already allocated */
2876 if (!strcmp (method
->method
->name
, ".ctor"))
2879 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2880 g_assert (!method
->method
->klass
->valuetype
);
2881 result
= mono_runtime_invoke_array (method
->method
, this, params
, NULL
);
2883 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
2884 if (sig
->params
[i
]->byref
) {
2886 arg
= mono_array_get (params
, gpointer
, i
);
2887 mono_array_setref (out_args
, j
, arg
);
2892 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2898 read_enum_value (char *mem
, int type
)
2902 return *(guint8
*)mem
;
2904 return *(gint8
*)mem
;
2906 return *(guint16
*)mem
;
2908 return *(gint16
*)mem
;
2910 return *(guint32
*)mem
;
2912 return *(gint32
*)mem
;
2914 return *(guint64
*)mem
;
2916 return *(gint64
*)mem
;
2918 g_assert_not_reached ();
2924 write_enum_value (char *mem
, int type
, guint64 value
)
2928 case MONO_TYPE_I1
: {
2929 guint8
*p
= (guint8
*)mem
;
2934 case MONO_TYPE_I2
: {
2935 guint16
*p
= (void*)mem
;
2940 case MONO_TYPE_I4
: {
2941 guint32
*p
= (void*)mem
;
2946 case MONO_TYPE_I8
: {
2947 guint64
*p
= (void*)mem
;
2952 g_assert_not_reached ();
2958 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, MonoObject
*value
)
2961 MonoClass
*enumc
, *objc
;
2966 MONO_ARCH_SAVE_REGS
;
2968 MONO_CHECK_ARG_NULL (enumType
);
2969 MONO_CHECK_ARG_NULL (value
);
2971 domain
= mono_object_domain (enumType
);
2972 enumc
= mono_class_from_mono_type (enumType
->type
);
2973 objc
= value
->vtable
->klass
;
2975 if (!enumc
->enumtype
)
2976 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2977 if (!((objc
->enumtype
) || (objc
->byval_arg
.type
>= MONO_TYPE_I1
&& objc
->byval_arg
.type
<= MONO_TYPE_U8
)))
2978 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."));
2980 etype
= mono_class_enum_basetype (enumc
);
2982 /* MS throws this for typebuilders */
2983 mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
2985 res
= mono_object_new (domain
, enumc
);
2986 val
= read_enum_value ((char *)value
+ sizeof (MonoObject
), objc
->enumtype
? mono_class_enum_basetype (objc
)->type
: objc
->byval_arg
.type
);
2987 write_enum_value ((char *)res
+ sizeof (MonoObject
), etype
->type
, val
);
2993 ves_icall_System_Enum_get_value (MonoObject
*this)
3001 MONO_ARCH_SAVE_REGS
;
3006 g_assert (this->vtable
->klass
->enumtype
);
3008 enumc
= mono_class_from_mono_type (mono_class_enum_basetype (this->vtable
->klass
));
3009 res
= mono_object_new (mono_object_domain (this), enumc
);
3010 dst
= (char *)res
+ sizeof (MonoObject
);
3011 src
= (char *)this + sizeof (MonoObject
);
3012 size
= mono_class_value_size (enumc
, NULL
);
3014 memcpy (dst
, src
, size
);
3019 static MonoReflectionType
*
3020 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3024 MONO_ARCH_SAVE_REGS
;
3026 etype
= mono_class_enum_basetype (mono_class_from_mono_type (type
->type
));
3028 /* MS throws this for typebuilders */
3029 mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType"));
3031 return mono_type_get_object (mono_object_domain (type
), etype
);
3035 ves_icall_System_Enum_compare_value_to (MonoObject
*this, MonoObject
*other
)
3037 gpointer tdata
= (char *)this + sizeof (MonoObject
);
3038 gpointer odata
= (char *)other
+ sizeof (MonoObject
);
3039 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3040 g_assert (basetype
);
3042 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3043 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3044 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3047 return me > other ? 1 : -1; \
3050 #define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
3051 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3052 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3055 return me - other; \
3058 switch (basetype
->type
) {
3060 COMPARE_ENUM_VALUES (guint8
);
3062 COMPARE_ENUM_VALUES (gint8
);
3063 case MONO_TYPE_CHAR
:
3065 COMPARE_ENUM_VALUES_RANGE (guint16
);
3067 COMPARE_ENUM_VALUES (gint16
);
3069 COMPARE_ENUM_VALUES (guint32
);
3071 COMPARE_ENUM_VALUES (gint32
);
3073 COMPARE_ENUM_VALUES (guint64
);
3075 COMPARE_ENUM_VALUES (gint64
);
3077 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3079 #undef COMPARE_ENUM_VALUES_RANGE
3080 #undef COMPARE_ENUM_VALUES
3085 ves_icall_System_Enum_get_hashcode (MonoObject
*this)
3087 gpointer data
= (char *)this + sizeof (MonoObject
);
3088 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3089 g_assert (basetype
);
3091 switch (basetype
->type
) {
3093 return *((gint8
*)data
);
3095 return *((guint8
*)data
);
3096 case MONO_TYPE_CHAR
:
3098 return *((guint16
*)data
);
3101 return *((gint16
*)data
);
3103 return *((guint32
*)data
);
3105 return *((gint32
*)data
);
3107 case MONO_TYPE_I8
: {
3108 gint64 value
= *((gint64
*)data
);
3109 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3112 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3118 ves_icall_get_enum_info (MonoReflectionType
*type
, MonoEnumInfo
*info
)
3120 MonoDomain
*domain
= mono_object_domain (type
);
3121 MonoClass
*enumc
= mono_class_from_mono_type (type
->type
);
3122 guint j
= 0, nvalues
, crow
;
3124 MonoClassField
*field
;
3126 MONO_ARCH_SAVE_REGS
;
3128 MONO_STRUCT_SETREF (info
, utype
, mono_type_get_object (domain
, mono_class_enum_basetype (enumc
)));
3129 nvalues
= mono_class_num_fields (enumc
) ? mono_class_num_fields (enumc
) - 1 : 0;
3130 MONO_STRUCT_SETREF (info
, names
, mono_array_new (domain
, mono_defaults
.string_class
, nvalues
));
3131 MONO_STRUCT_SETREF (info
, values
, mono_array_new (domain
, enumc
, nvalues
));
3135 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3138 MonoTypeEnum def_type
;
3140 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3142 if (mono_field_is_deleted (field
))
3144 mono_array_setref (info
->names
, j
, mono_string_new (domain
, mono_field_get_name (field
)));
3146 p
= mono_class_get_field_default_value (field
, &def_type
);
3147 len
= mono_metadata_decode_blob_size (p
, &p
);
3148 switch (mono_class_enum_basetype (enumc
)->type
) {
3151 mono_array_set (info
->values
, gchar
, j
, *p
);
3153 case MONO_TYPE_CHAR
:
3156 mono_array_set (info
->values
, gint16
, j
, read16 (p
));
3160 mono_array_set (info
->values
, gint32
, j
, read32 (p
));
3164 mono_array_set (info
->values
, gint64
, j
, read64 (p
));
3167 g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc
)->type
);
3174 BFLAGS_IgnoreCase
= 1,
3175 BFLAGS_DeclaredOnly
= 2,
3176 BFLAGS_Instance
= 4,
3178 BFLAGS_Public
= 0x10,
3179 BFLAGS_NonPublic
= 0x20,
3180 BFLAGS_FlattenHierarchy
= 0x40,
3181 BFLAGS_InvokeMethod
= 0x100,
3182 BFLAGS_CreateInstance
= 0x200,
3183 BFLAGS_GetField
= 0x400,
3184 BFLAGS_SetField
= 0x800,
3185 BFLAGS_GetProperty
= 0x1000,
3186 BFLAGS_SetProperty
= 0x2000,
3187 BFLAGS_ExactBinding
= 0x10000,
3188 BFLAGS_SuppressChangeType
= 0x20000,
3189 BFLAGS_OptionalParamBinding
= 0x40000
3192 static MonoReflectionField
*
3193 ves_icall_Type_GetField (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3196 MonoClass
*startklass
, *klass
;
3198 MonoClassField
*field
;
3201 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3202 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3203 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3205 MONO_ARCH_SAVE_REGS
;
3208 mono_raise_exception (mono_get_exception_argument_null ("name"));
3209 if (type
->type
->byref
)
3212 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? mono_utf8_strcasecmp
: strcmp
;
3215 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3216 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3219 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3222 if (field
->type
== NULL
)
3224 if (mono_field_is_deleted (field
))
3226 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3227 if (bflags
& BFLAGS_Public
)
3229 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3230 if (bflags
& BFLAGS_NonPublic
) {
3237 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3238 if (bflags
& BFLAGS_Static
)
3239 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3242 if (bflags
& BFLAGS_Instance
)
3249 utf8_name
= mono_string_to_utf8 (name
);
3251 if (compare_func (mono_field_get_name (field
), utf8_name
)) {
3257 return mono_field_get_object (domain
, klass
, field
);
3259 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3266 ves_icall_Type_GetFields_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3269 MonoClass
*startklass
, *klass
, *refklass
;
3274 MonoClassField
*field
;
3275 MonoPtrArray tmp_array
;
3277 MONO_ARCH_SAVE_REGS
;
3279 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3280 if (type
->type
->byref
)
3281 return mono_array_new (domain
, mono_defaults
.field_info_class
, 0);
3282 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3283 refklass
= mono_class_from_mono_type (reftype
->type
);
3285 mono_ptr_array_init (tmp_array
, 2);
3288 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3289 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3292 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3294 if (mono_field_is_deleted (field
))
3296 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3297 if (bflags
& BFLAGS_Public
)
3299 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3300 if (bflags
& BFLAGS_NonPublic
) {
3307 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3308 if (bflags
& BFLAGS_Static
)
3309 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3312 if (bflags
& BFLAGS_Instance
)
3318 member
= (MonoObject
*)mono_field_get_object (domain
, refklass
, field
);
3319 mono_ptr_array_append (tmp_array
, member
);
3321 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3324 res
= mono_array_new_cached (domain
, mono_defaults
.field_info_class
, mono_ptr_array_size (tmp_array
));
3326 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3327 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3329 mono_ptr_array_destroy (tmp_array
);
3335 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3337 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3338 case METHOD_ATTRIBUTE_ASSEM
:
3339 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3340 case METHOD_ATTRIBUTE_PRIVATE
:
3342 case METHOD_ATTRIBUTE_PUBLIC
:
3350 ves_icall_Type_GetMethodsByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3352 static MonoClass
*MethodInfo_array
;
3354 MonoClass
*startklass
, *klass
, *refklass
;
3359 int i
, len
, match
, nslots
;
3360 /*FIXME, use MonoBitSet*/
3361 guint32 method_slots_default
[8];
3362 guint32
*method_slots
= NULL
;
3363 gchar
*mname
= NULL
;
3364 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3365 MonoVTable
*array_vtable
;
3367 MonoPtrArray tmp_array
;
3369 MONO_ARCH_SAVE_REGS
;
3371 mono_ptr_array_init (tmp_array
, 4);
3373 if (!MethodInfo_array
) {
3374 MonoClass
*klass
= mono_array_class_get (mono_defaults
.method_info_class
, 1);
3375 mono_memory_barrier ();
3376 MethodInfo_array
= klass
;
3379 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3380 array_vtable
= mono_class_vtable_full (domain
, MethodInfo_array
, TRUE
);
3381 if (type
->type
->byref
)
3382 return mono_array_new_specific (array_vtable
, 0);
3383 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3384 refklass
= mono_class_from_mono_type (reftype
->type
);
3387 mname
= mono_string_to_utf8 (name
);
3388 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3391 /* An optimization for calls made from Delegate:CreateDelegate () */
3392 if (klass
->delegate
&& mname
&& !strcmp (mname
, "Invoke") && (bflags
== (BFLAGS_Public
| BFLAGS_Static
| BFLAGS_Instance
))) {
3393 method
= mono_get_delegate_invoke (klass
);
3394 if (mono_loader_get_last_error ())
3397 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3399 res
= mono_array_new_specific (array_vtable
, 1);
3400 mono_array_setref (res
, 0, member
);
3405 mono_class_setup_vtable (klass
);
3406 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3409 if (is_generic_parameter (type
->type
))
3410 nslots
= mono_class_get_vtable_size (klass
->parent
);
3412 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : mono_class_get_vtable_size (klass
);
3413 if (nslots
>= sizeof (method_slots_default
) * 8) {
3414 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3416 method_slots
= method_slots_default
;
3417 memset (method_slots
, 0, sizeof (method_slots_default
));
3420 mono_class_setup_vtable (klass
);
3421 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3425 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3427 if (method
->slot
!= -1) {
3428 g_assert (method
->slot
< nslots
);
3429 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3431 if (!(method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
))
3432 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3435 if (method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3437 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3438 if (bflags
& BFLAGS_Public
)
3440 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3446 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3447 if (bflags
& BFLAGS_Static
)
3448 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3451 if (bflags
& BFLAGS_Instance
)
3459 if (compare_func (mname
, method
->name
))
3465 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3467 mono_ptr_array_append (tmp_array
, member
);
3469 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3473 if (method_slots
!= method_slots_default
)
3474 g_free (method_slots
);
3476 res
= mono_array_new_specific (array_vtable
, mono_ptr_array_size (tmp_array
));
3478 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3479 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3481 mono_ptr_array_destroy (tmp_array
);
3486 if (method_slots
!= method_slots_default
)
3487 g_free (method_slots
);
3488 mono_ptr_array_destroy (tmp_array
);
3489 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3490 ex
= mono_class_get_exception_for_failure (klass
);
3492 ex
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
3493 mono_loader_clear_error ();
3495 mono_raise_exception (ex
);
3500 ves_icall_Type_GetConstructors_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3503 static MonoClass
*System_Reflection_ConstructorInfo
;
3504 MonoClass
*startklass
, *klass
, *refklass
;
3509 gpointer iter
= NULL
;
3510 MonoPtrArray tmp_array
;
3512 MONO_ARCH_SAVE_REGS
;
3514 mono_ptr_array_init (tmp_array
, 4); /*FIXME, guestimating*/
3516 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3517 if (type
->type
->byref
)
3518 return mono_array_new_cached (domain
, mono_defaults
.method_info_class
, 0);
3519 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3520 refklass
= mono_class_from_mono_type (reftype
->type
);
3522 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3523 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3525 if (!System_Reflection_ConstructorInfo
)
3526 System_Reflection_ConstructorInfo
= mono_class_from_name (
3527 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
3530 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3532 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
3534 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3535 if (bflags
& BFLAGS_Public
)
3538 if (bflags
& BFLAGS_NonPublic
)
3544 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3545 if (bflags
& BFLAGS_Static
)
3546 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3549 if (bflags
& BFLAGS_Instance
)
3555 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3557 mono_ptr_array_append (tmp_array
, member
);
3560 res
= mono_array_new_cached (domain
, System_Reflection_ConstructorInfo
, mono_ptr_array_size (tmp_array
));
3562 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3563 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3565 mono_ptr_array_destroy (tmp_array
);
3571 property_hash (gconstpointer data
)
3573 MonoProperty
*prop
= (MonoProperty
*)data
;
3575 return g_str_hash (prop
->name
);
3579 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
3581 // Properties are hide-by-name-and-signature
3582 if (!g_str_equal (prop1
->name
, prop2
->name
))
3585 if (prop1
->get
&& prop2
->get
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->get
), mono_method_signature (prop2
->get
)))
3587 if (prop1
->set
&& prop2
->set
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->set
), mono_method_signature (prop2
->set
)))
3593 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
3598 return method_nonpublic (accessor
, start_klass
);
3602 ves_icall_Type_GetPropertiesByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3605 static MonoClass
*System_Reflection_PropertyInfo
;
3606 MonoClass
*startklass
, *klass
;
3612 gchar
*propname
= NULL
;
3613 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3615 GHashTable
*properties
;
3616 MonoPtrArray tmp_array
;
3618 MONO_ARCH_SAVE_REGS
;
3620 mono_ptr_array_init (tmp_array
, 8); /*This the average for ASP.NET types*/
3622 if (!System_Reflection_PropertyInfo
)
3623 System_Reflection_PropertyInfo
= mono_class_from_name (
3624 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
3626 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3627 if (type
->type
->byref
)
3628 return mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, 0);
3629 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3631 propname
= mono_string_to_utf8 (name
);
3632 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3635 mono_class_setup_vtable (klass
);
3637 properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
3639 mono_class_setup_vtable (klass
);
3640 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3641 g_hash_table_destroy (properties
);
3644 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3648 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
3654 flags
= method
->flags
;
3657 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
3658 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
3659 if (bflags
& BFLAGS_Public
)
3661 } else if (bflags
& BFLAGS_NonPublic
) {
3662 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
3663 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
3670 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
3671 if (bflags
& BFLAGS_Static
)
3672 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3675 if (bflags
& BFLAGS_Instance
)
3684 if (compare_func (propname
, prop
->name
))
3688 if (g_hash_table_lookup (properties
, prop
))
3691 mono_ptr_array_append (tmp_array
, mono_property_get_object (domain
, startklass
, prop
));
3693 g_hash_table_insert (properties
, prop
, prop
);
3695 if ((!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
)))
3698 g_hash_table_destroy (properties
);
3701 res
= mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, mono_ptr_array_size (tmp_array
));
3702 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3703 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3705 mono_ptr_array_destroy (tmp_array
);
3710 static MonoReflectionEvent
*
3711 ves_icall_MonoType_GetEvent (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3714 MonoClass
*klass
, *startklass
;
3720 MONO_ARCH_SAVE_REGS
;
3722 event_name
= mono_string_to_utf8 (name
);
3723 if (type
->type
->byref
)
3725 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3726 domain
= mono_object_domain (type
);
3729 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3730 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3733 while ((event
= mono_class_get_events (klass
, &iter
))) {
3734 if (strcmp (event
->name
, event_name
))
3737 method
= event
->add
;
3739 method
= event
->remove
;
3741 method
= event
->raise
;
3743 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3744 if (!(bflags
& BFLAGS_Public
))
3747 if (!(bflags
& BFLAGS_NonPublic
))
3749 if ((klass
!= startklass
) && (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PRIVATE
)
3753 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3754 if (!(bflags
& BFLAGS_Static
))
3756 if (!(bflags
& BFLAGS_FlattenHierarchy
) && (klass
!= startklass
))
3759 if (!(bflags
& BFLAGS_Instance
))
3763 if (!(bflags
& BFLAGS_NonPublic
))
3766 g_free (event_name
);
3767 return mono_event_get_object (domain
, startklass
, event
);
3770 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3773 g_free (event_name
);
3778 ves_icall_Type_GetEvents_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3781 static MonoClass
*System_Reflection_EventInfo
;
3782 MonoClass
*startklass
, *klass
;
3789 MonoPtrArray tmp_array
;
3791 MONO_ARCH_SAVE_REGS
;
3793 mono_ptr_array_init (tmp_array
, 4);
3795 if (!System_Reflection_EventInfo
)
3796 System_Reflection_EventInfo
= mono_class_from_name (
3797 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
3799 domain
= mono_object_domain (type
);
3800 if (type
->type
->byref
)
3801 return mono_array_new_cached (domain
, System_Reflection_EventInfo
, 0);
3802 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3805 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3806 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3809 while ((event
= mono_class_get_events (klass
, &iter
))) {
3811 method
= event
->add
;
3813 method
= event
->remove
;
3815 method
= event
->raise
;
3817 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3818 if (bflags
& BFLAGS_Public
)
3820 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
3821 if (bflags
& BFLAGS_NonPublic
)
3826 if (bflags
& BFLAGS_NonPublic
)
3832 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3833 if (bflags
& BFLAGS_Static
)
3834 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3837 if (bflags
& BFLAGS_Instance
)
3842 if (bflags
& BFLAGS_Instance
)
3846 mono_ptr_array_append (tmp_array
, mono_event_get_object (domain
, startklass
, event
));
3848 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3851 res
= mono_array_new_cached (domain
, System_Reflection_EventInfo
, mono_ptr_array_size (tmp_array
));
3853 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3854 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3856 mono_ptr_array_destroy (tmp_array
);
3861 static MonoReflectionType
*
3862 ves_icall_Type_GetNestedType (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3870 MONO_ARCH_SAVE_REGS
;
3873 mono_raise_exception (mono_get_exception_argument_null ("name"));
3875 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3876 if (type
->type
->byref
)
3878 klass
= mono_class_from_mono_type (type
->type
);
3879 str
= mono_string_to_utf8 (name
);
3882 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3883 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3886 * If a nested type is generic, return its generic type definition.
3887 * Note that this means that the return value is essentially a
3888 * nested type of the generic type definition of @klass.
3890 * A note in MSDN claims that a generic type definition can have
3891 * nested types that aren't generic. In any case, the container of that
3892 * nested type would be the generic type definition.
3894 if (klass
->generic_class
)
3895 klass
= klass
->generic_class
->container_class
;
3898 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
3900 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
3901 if (bflags
& BFLAGS_Public
)
3904 if (bflags
& BFLAGS_NonPublic
)
3909 if (strcmp (nested
->name
, str
) == 0){
3911 return mono_type_get_object (domain
, &nested
->byval_arg
);
3914 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3921 ves_icall_Type_GetNestedTypes (MonoReflectionType
*type
, guint32 bflags
)
3930 MonoPtrArray tmp_array
;
3932 MONO_ARCH_SAVE_REGS
;
3934 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3935 if (type
->type
->byref
)
3936 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
3937 klass
= mono_class_from_mono_type (type
->type
);
3938 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3939 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3942 * If a nested type is generic, return its generic type definition.
3943 * Note that this means that the return value is essentially the set
3944 * of nested types of the generic type definition of @klass.
3946 * A note in MSDN claims that a generic type definition can have
3947 * nested types that aren't generic. In any case, the container of that
3948 * nested type would be the generic type definition.
3950 if (klass
->generic_class
)
3951 klass
= klass
->generic_class
->container_class
;
3953 mono_ptr_array_init (tmp_array
, 1);
3955 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
3957 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
3958 if (bflags
& BFLAGS_Public
)
3961 if (bflags
& BFLAGS_NonPublic
)
3966 member
= (MonoObject
*)mono_type_get_object (domain
, &nested
->byval_arg
);
3967 mono_ptr_array_append (tmp_array
, member
);
3970 res
= mono_array_new_cached (domain
, mono_defaults
.monotype_class
, mono_ptr_array_size (tmp_array
));
3972 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3973 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3975 mono_ptr_array_destroy (tmp_array
);
3980 static MonoReflectionType
*
3981 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly
*assembly
, MonoReflectionModule
*module
, MonoString
*name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
)
3984 MonoType
*type
= NULL
;
3985 MonoTypeNameParse info
;
3986 gboolean type_resolve
;
3988 MONO_ARCH_SAVE_REGS
;
3990 /* On MS.NET, this does not fire a TypeResolve event */
3991 type_resolve
= TRUE
;
3992 str
= mono_string_to_utf8 (name
);
3993 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3994 if (!mono_reflection_parse_type (str
, &info
)) {
3996 mono_reflection_free_type_info (&info
);
3997 if (throwOnError
) /* uhm: this is a parse error, though... */
3998 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
3999 /*g_print ("failed parse\n");*/
4003 if (info
.assembly
.name
) {
4005 mono_reflection_free_type_info (&info
);
4007 /* 1.0 and 2.0 throw different exceptions */
4008 if (mono_defaults
.generic_ilist_class
)
4009 mono_raise_exception (mono_get_exception_argument (NULL
, "Type names passed to Assembly.GetType() must not specify an assembly."));
4011 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4016 if (module
!= NULL
) {
4018 type
= mono_reflection_get_type (module
->image
, &info
, ignoreCase
, &type_resolve
);
4023 if (assembly
->assembly
->dynamic
) {
4024 /* Enumerate all modules */
4025 MonoReflectionAssemblyBuilder
*abuilder
= (MonoReflectionAssemblyBuilder
*)assembly
;
4029 if (abuilder
->modules
) {
4030 for (i
= 0; i
< mono_array_length (abuilder
->modules
); ++i
) {
4031 MonoReflectionModuleBuilder
*mb
= mono_array_get (abuilder
->modules
, MonoReflectionModuleBuilder
*, i
);
4032 type
= mono_reflection_get_type (&mb
->dynamic_image
->image
, &info
, ignoreCase
, &type_resolve
);
4038 if (!type
&& abuilder
->loaded_modules
) {
4039 for (i
= 0; i
< mono_array_length (abuilder
->loaded_modules
); ++i
) {
4040 MonoReflectionModule
*mod
= mono_array_get (abuilder
->loaded_modules
, MonoReflectionModule
*, i
);
4041 type
= mono_reflection_get_type (mod
->image
, &info
, ignoreCase
, &type_resolve
);
4048 type
= mono_reflection_get_type (assembly
->assembly
->image
, &info
, ignoreCase
, &type_resolve
);
4050 mono_reflection_free_type_info (&info
);
4052 MonoException
*e
= NULL
;
4055 e
= mono_get_exception_type_load (name
, NULL
);
4057 if (mono_loader_get_last_error () && mono_defaults
.generic_ilist_class
)
4058 e
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
4060 mono_loader_clear_error ();
4063 mono_raise_exception (e
);
4068 if (type
->type
== MONO_TYPE_CLASS
) {
4069 MonoClass
*klass
= mono_type_get_class (type
);
4071 if (mono_is_security_manager_active () && !klass
->exception_type
)
4072 /* Some security problems are detected during generic vtable construction */
4073 mono_class_setup_vtable (klass
);
4074 /* need to report exceptions ? */
4075 if (throwOnError
&& klass
->exception_type
) {
4076 /* report SecurityException (or others) that occured when loading the assembly */
4077 MonoException
*exc
= mono_class_get_exception_for_failure (klass
);
4078 mono_loader_clear_error ();
4079 mono_raise_exception (exc
);
4080 } else if (klass
->exception_type
== MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND
) {
4085 /* g_print ("got it\n"); */
4086 return mono_type_get_object (mono_object_domain (assembly
), type
);
4090 replace_shadow_path (MonoDomain
*domain
, gchar
*dirname
, gchar
**filename
)
4093 gchar
*shadow_ini_file
;
4096 /* Check for shadow-copied assembly */
4097 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4098 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4100 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4101 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4107 g_free (shadow_ini_file
);
4108 if (content
!= NULL
) {
4111 *filename
= content
;
4119 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly
*assembly
, MonoBoolean escaped
)
4121 MonoDomain
*domain
= mono_object_domain (assembly
);
4122 MonoAssembly
*mass
= assembly
->assembly
;
4123 MonoString
*res
= NULL
;
4128 MONO_ARCH_SAVE_REGS
;
4130 if (g_path_is_absolute (mass
->image
->name
)) {
4131 absolute
= g_strdup (mass
->image
->name
);
4132 dirname
= g_path_get_dirname (absolute
);
4134 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4135 dirname
= g_strdup (mass
->basedir
);
4138 replace_shadow_path (domain
, dirname
, &absolute
);
4143 for (i
= strlen (absolute
) - 1; i
>= 0; i
--)
4144 if (absolute
[i
] == '\\')
4149 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4151 const char *prepend
= "file://";
4153 if (*absolute
== '/' && *(absolute
+ 1) == '/') {
4156 prepend
= "file:///";
4159 uri
= g_strconcat (prepend
, absolute
, NULL
);
4163 res
= mono_string_new (domain
, uri
);
4171 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly
*assembly
)
4173 MonoAssembly
*mass
= assembly
->assembly
;
4175 MONO_ARCH_SAVE_REGS
;
4177 return mass
->in_gac
;
4180 static MonoReflectionAssembly
*
4181 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString
*mname
, MonoObject
*evidence
)
4185 MonoImageOpenStatus status
;
4187 MONO_ARCH_SAVE_REGS
;
4189 name
= mono_string_to_utf8 (mname
);
4190 res
= mono_assembly_load_with_partial_name (name
, &status
);
4196 return mono_assembly_get_object (mono_domain_get (), res
);
4200 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly
*assembly
)
4202 MonoDomain
*domain
= mono_object_domain (assembly
);
4205 MONO_ARCH_SAVE_REGS
;
4207 res
= mono_string_new (domain
, mono_image_get_filename (assembly
->assembly
->image
));
4213 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
*assembly
)
4215 MONO_ARCH_SAVE_REGS
;
4217 return assembly
->assembly
->ref_only
;
4221 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly
*assembly
)
4223 MonoDomain
*domain
= mono_object_domain (assembly
);
4225 MONO_ARCH_SAVE_REGS
;
4227 return mono_string_new (domain
, assembly
->assembly
->image
->version
);
4230 static MonoReflectionMethod
*
4231 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly
*assembly
)
4233 guint32 token
= mono_image_get_entry_point (assembly
->assembly
->image
);
4235 MONO_ARCH_SAVE_REGS
;
4239 return mono_method_get_object (mono_object_domain (assembly
), mono_get_method (assembly
->assembly
->image
, token
, NULL
), NULL
);
4242 static MonoReflectionModule
*
4243 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly
*assembly
)
4245 return mono_module_get_object (mono_object_domain (assembly
), assembly
->assembly
->image
);
4249 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly
*assembly
)
4251 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4252 MonoArray
*result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, table
->rows
);
4256 MONO_ARCH_SAVE_REGS
;
4258 for (i
= 0; i
< table
->rows
; ++i
) {
4259 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4260 mono_array_setref (result
, i
, mono_string_new (mono_object_domain (assembly
), val
));
4266 create_version (MonoDomain
*domain
, guint32 major
, guint32 minor
, guint32 build
, guint32 revision
)
4268 static MonoClass
*System_Version
= NULL
;
4269 static MonoMethod
*create_version
= NULL
;
4273 if (!System_Version
) {
4274 System_Version
= mono_class_from_name (mono_defaults
.corlib
, "System", "Version");
4275 g_assert (System_Version
);
4278 if (!create_version
) {
4279 MonoMethodDesc
*desc
= mono_method_desc_new (":.ctor(int,int,int,int)", FALSE
);
4280 create_version
= mono_method_desc_search_in_class (desc
, System_Version
);
4281 g_assert (create_version
);
4282 mono_method_desc_free (desc
);
4288 args
[3] = &revision
;
4289 result
= mono_object_new (domain
, System_Version
);
4290 mono_runtime_invoke (create_version
, result
, args
, NULL
);
4296 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly
*assembly
)
4298 static MonoClass
*System_Reflection_AssemblyName
;
4300 MonoDomain
*domain
= mono_object_domain (assembly
);
4302 static MonoMethod
*create_culture
= NULL
;
4303 MonoImage
*image
= assembly
->assembly
->image
;
4306 MONO_ARCH_SAVE_REGS
;
4308 if (!System_Reflection_AssemblyName
)
4309 System_Reflection_AssemblyName
= mono_class_from_name (
4310 mono_defaults
.corlib
, "System.Reflection", "AssemblyName");
4312 t
= &assembly
->assembly
->image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4315 result
= mono_array_new (domain
, System_Reflection_AssemblyName
, count
);
4317 if (count
> 0 && !create_culture
) {
4318 MonoMethodDesc
*desc
= mono_method_desc_new (
4319 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4320 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4321 g_assert (create_culture
);
4322 mono_method_desc_free (desc
);
4325 for (i
= 0; i
< count
; i
++) {
4326 MonoReflectionAssemblyName
*aname
;
4327 guint32 cols
[MONO_ASSEMBLYREF_SIZE
];
4329 mono_metadata_decode_row (t
, i
, cols
, MONO_ASSEMBLYREF_SIZE
);
4331 aname
= (MonoReflectionAssemblyName
*) mono_object_new (
4332 domain
, System_Reflection_AssemblyName
);
4334 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_NAME
])));
4336 aname
->major
= cols
[MONO_ASSEMBLYREF_MAJOR_VERSION
];
4337 aname
->minor
= cols
[MONO_ASSEMBLYREF_MINOR_VERSION
];
4338 aname
->build
= cols
[MONO_ASSEMBLYREF_BUILD_NUMBER
];
4339 aname
->revision
= cols
[MONO_ASSEMBLYREF_REV_NUMBER
];
4340 aname
->flags
= cols
[MONO_ASSEMBLYREF_FLAGS
];
4341 aname
->versioncompat
= 1; /* SameMachine (default) */
4342 aname
->hashalg
= ASSEMBLY_HASH_SHA1
; /* SHA1 (default) */
4343 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, aname
->major
, aname
->minor
, aname
->build
, aname
->revision
));
4345 if (create_culture
) {
4347 MonoBoolean assembly_ref
= 1;
4348 args
[0] = mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_CULTURE
]));
4349 args
[1] = &assembly_ref
;
4350 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4353 if (cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]) {
4354 const gchar
*pkey_ptr
= mono_metadata_blob_heap (image
, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]);
4355 guint32 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4357 if ((cols
[MONO_ASSEMBLYREF_FLAGS
] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
)) {
4358 /* public key token isn't copied - the class library will
4359 automatically generate it from the public key if required */
4360 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4361 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4363 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4364 memcpy (mono_array_addr (aname
->keyToken
, guint8
, 0), pkey_ptr
, pkey_len
);
4367 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4370 /* note: this function doesn't return the codebase on purpose (i.e. it can
4371 be used under partial trust as path information isn't present). */
4373 mono_array_setref (result
, i
, aname
);
4384 foreach_namespace (const char* key
, gconstpointer val
, NameSpaceInfo
*info
)
4386 MonoString
*name
= mono_string_new (mono_object_domain (info
->res
), key
);
4388 mono_array_setref (info
->res
, info
->idx
, name
);
4393 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly
*assembly
)
4395 MonoImage
*img
= assembly
->assembly
->image
;
4400 MONO_ARCH_SAVE_REGS
;
4402 mono_image_lock (img
);
4403 mono_image_init_name_cache (img
);
4406 len
= g_hash_table_size (img
->name_cache
);
4407 mono_image_unlock (img
);
4409 /*we can't create objects holding the image lock */
4410 res
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, len
);
4412 mono_image_lock (img
);
4413 /*len might have changed, create a new array*/
4414 if (len
!= g_hash_table_size (img
->name_cache
))
4419 g_hash_table_foreach (img
->name_cache
, (GHFunc
)foreach_namespace
, &info
);
4420 mono_image_unlock (img
);
4425 /* move this in some file in mono/util/ */
4427 g_concat_dir_and_file (const char *dir
, const char *file
)
4429 g_return_val_if_fail (dir
!= NULL
, NULL
);
4430 g_return_val_if_fail (file
!= NULL
, NULL
);
4433 * If the directory name doesn't have a / on the end, we need
4434 * to add one so we get a proper path to the file
4436 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4437 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4439 return g_strconcat (dir
, file
, NULL
);
4443 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, gint32
*size
, MonoReflectionModule
**ref_module
)
4445 char *n
= mono_string_to_utf8 (name
);
4446 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4448 guint32 cols
[MONO_MANIFEST_SIZE
];
4449 guint32 impl
, file_idx
;
4453 MONO_ARCH_SAVE_REGS
;
4455 for (i
= 0; i
< table
->rows
; ++i
) {
4456 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4457 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4458 if (strcmp (val
, n
) == 0)
4462 if (i
== table
->rows
)
4465 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4468 * this code should only be called after obtaining the
4469 * ResourceInfo and handling the other cases.
4471 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4472 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4474 module
= mono_image_load_file_for_image (assembly
->assembly
->image
, file_idx
);
4479 module
= assembly
->assembly
->image
;
4481 mono_gc_wbarrier_generic_store (ref_module
, (MonoObject
*) mono_module_get_object (mono_domain_get (), module
));
4483 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4487 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoManifestResourceInfo
*info
)
4489 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4491 guint32 cols
[MONO_MANIFEST_SIZE
];
4492 guint32 file_cols
[MONO_FILE_SIZE
];
4496 MONO_ARCH_SAVE_REGS
;
4498 n
= mono_string_to_utf8 (name
);
4499 for (i
= 0; i
< table
->rows
; ++i
) {
4500 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4501 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4502 if (strcmp (val
, n
) == 0)
4506 if (i
== table
->rows
)
4509 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4510 info
->location
= RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
;
4513 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4514 case MONO_IMPLEMENTATION_FILE
:
4515 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4516 table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4517 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4518 val
= mono_metadata_string_heap (assembly
->assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4519 MONO_OBJECT_SETREF (info
, filename
, mono_string_new (mono_object_domain (assembly
), val
));
4520 if (file_cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4523 info
->location
= RESOURCE_LOCATION_EMBEDDED
;
4526 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4527 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4528 mono_assembly_load_reference (assembly
->assembly
->image
, i
- 1);
4529 if (assembly
->assembly
->image
->references
[i
- 1] == (gpointer
)-1) {
4530 char *msg
= g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->assembly
->image
->name
);
4531 MonoException
*ex
= mono_get_exception_file_not_found2 (msg
, NULL
);
4533 mono_raise_exception (ex
);
4535 MONO_OBJECT_SETREF (info
, assembly
, mono_assembly_get_object (mono_domain_get (), assembly
->assembly
->image
->references
[i
- 1]));
4537 /* Obtain info recursively */
4538 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info
->assembly
, name
, info
);
4539 info
->location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4542 case MONO_IMPLEMENTATION_EXP_TYPE
:
4543 g_assert_not_reached ();
4552 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoBoolean resource_modules
)
4554 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4555 MonoArray
*result
= NULL
;
4560 MONO_ARCH_SAVE_REGS
;
4562 /* check hash if needed */
4564 n
= mono_string_to_utf8 (name
);
4565 for (i
= 0; i
< table
->rows
; ++i
) {
4566 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4567 if (strcmp (val
, n
) == 0) {
4570 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4571 fn
= mono_string_new (mono_object_domain (assembly
), n
);
4573 return (MonoObject
*)fn
;
4581 for (i
= 0; i
< table
->rows
; ++i
) {
4582 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
4586 result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, count
);
4589 for (i
= 0; i
< table
->rows
; ++i
) {
4590 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
4591 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4592 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4593 mono_array_setref (result
, count
, mono_string_new (mono_object_domain (assembly
), n
));
4598 return (MonoObject
*)result
;
4602 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
*assembly
)
4604 MonoDomain
*domain
= mono_domain_get();
4607 int i
, j
, file_count
= 0;
4608 MonoImage
**modules
;
4609 guint32 module_count
, real_module_count
;
4610 MonoTableInfo
*table
;
4611 guint32 cols
[MONO_FILE_SIZE
];
4612 MonoImage
*image
= assembly
->assembly
->image
;
4614 g_assert (image
!= NULL
);
4615 g_assert (!assembly
->assembly
->dynamic
);
4617 table
= &image
->tables
[MONO_TABLE_FILE
];
4618 file_count
= table
->rows
;
4620 modules
= image
->modules
;
4621 module_count
= image
->module_count
;
4623 real_module_count
= 0;
4624 for (i
= 0; i
< module_count
; ++i
)
4626 real_module_count
++;
4628 klass
= mono_class_from_name (mono_defaults
.corlib
, "System.Reflection", "Module");
4629 res
= mono_array_new (domain
, klass
, 1 + real_module_count
+ file_count
);
4631 mono_array_setref (res
, 0, mono_module_get_object (domain
, image
));
4633 for (i
= 0; i
< module_count
; ++i
)
4635 mono_array_setref (res
, j
, mono_module_get_object (domain
, modules
[i
]));
4639 for (i
= 0; i
< file_count
; ++i
, ++j
) {
4640 mono_metadata_decode_row (table
, i
, cols
, MONO_FILE_SIZE
);
4641 if (cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4642 mono_array_setref (res
, j
, mono_module_file_get_object (domain
, image
, i
));
4644 MonoImage
*m
= mono_image_load_file_for_image (image
, i
+ 1);
4646 MonoString
*fname
= mono_string_new (mono_domain_get (), mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]));
4647 mono_raise_exception (mono_get_exception_file_not_found2 (NULL
, fname
));
4649 mono_array_setref (res
, j
, mono_module_get_object (domain
, m
));
4656 static MonoReflectionMethod
*
4657 ves_icall_GetCurrentMethod (void)
4659 MonoMethod
*m
= mono_method_get_last_managed ();
4661 while (m
->is_inflated
)
4662 m
= ((MonoMethodInflated
*)m
)->declaring
;
4664 return mono_method_get_object (mono_domain_get (), m
, NULL
);
4669 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
4672 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
4673 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
4674 //method is inflated, we should inflate it on the other class
4675 MonoGenericContext ctx
;
4676 ctx
.method_inst
= inflated
->context
.method_inst
;
4677 ctx
.class_inst
= inflated
->context
.class_inst
;
4678 if (klass
->generic_class
)
4679 ctx
.class_inst
= klass
->generic_class
->context
.class_inst
;
4680 else if (klass
->generic_container
)
4681 ctx
.class_inst
= klass
->generic_container
->context
.class_inst
;
4682 return mono_class_inflate_generic_method_full (inflated
->declaring
, klass
, &ctx
);
4685 mono_class_setup_methods (method
->klass
);
4686 if (method
->klass
->exception_type
)
4688 for (i
= 0; i
< method
->klass
->method
.count
; ++i
) {
4689 if (method
->klass
->methods
[i
] == method
) {
4694 mono_class_setup_methods (klass
);
4695 if (klass
->exception_type
)
4697 g_assert (offset
>= 0 && offset
< klass
->method
.count
);
4698 return klass
->methods
[offset
];
4701 static MonoReflectionMethod
*
4702 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod
*method
, MonoType
*type
)
4706 klass
= mono_class_from_mono_type (type
);
4707 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
4709 if (method
->klass
!= klass
) {
4710 method
= mono_method_get_equivalent_method (method
, klass
);
4715 klass
= method
->klass
;
4716 return mono_method_get_object (mono_domain_get (), method
, klass
);
4719 static MonoReflectionMethod
*
4720 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod
*method
)
4722 return mono_method_get_object (mono_domain_get (), method
, NULL
);
4725 static MonoReflectionMethodBody
*
4726 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
)
4728 return mono_method_body_get_object (mono_domain_get (), method
);
4731 static MonoReflectionAssembly
*
4732 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4734 MonoMethod
*dest
= NULL
;
4736 MONO_ARCH_SAVE_REGS
;
4738 mono_stack_walk_no_il (get_executing
, &dest
);
4739 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4743 static MonoReflectionAssembly
*
4744 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4746 MonoDomain
* domain
= mono_domain_get ();
4748 MONO_ARCH_SAVE_REGS
;
4750 if (!domain
->entry_assembly
)
4753 return mono_assembly_get_object (domain
, domain
->entry_assembly
);
4756 static MonoReflectionAssembly
*
4757 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4762 MONO_ARCH_SAVE_REGS
;
4765 mono_stack_walk_no_il (get_executing
, &dest
);
4767 mono_stack_walk_no_il (get_caller
, &dest
);
4770 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4774 ves_icall_System_MonoType_getFullName (MonoReflectionType
*object
, gboolean full_name
,
4775 gboolean assembly_qualified
)
4777 MonoDomain
*domain
= mono_object_domain (object
);
4778 MonoTypeNameFormat format
;
4782 MONO_ARCH_SAVE_REGS
;
4784 format
= assembly_qualified
?
4785 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
4786 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
4788 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
4790 name
= mono_type_get_name_full (object
->type
, format
);
4794 if (full_name
&& (object
->type
->type
== MONO_TYPE_VAR
|| object
->type
->type
== MONO_TYPE_MVAR
)) {
4799 res
= mono_string_new (domain
, name
);
4806 vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType
*this)
4808 MonoClass
*klass
= mono_class_from_mono_type (this->type
);
4809 return mono_security_core_clr_class_level (klass
);
4813 fill_reflection_assembly_name (MonoDomain
*domain
, MonoReflectionAssemblyName
*aname
, MonoAssemblyName
*name
, const char *absolute
, gboolean by_default_version
, gboolean default_publickey
, gboolean default_token
)
4815 static MonoMethod
*create_culture
= NULL
;
4818 const char *pkey_ptr
;
4820 MonoBoolean assembly_ref
= 0;
4822 MONO_ARCH_SAVE_REGS
;
4824 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, name
->name
));
4825 aname
->major
= name
->major
;
4826 aname
->minor
= name
->minor
;
4827 aname
->build
= name
->build
;
4828 aname
->flags
= name
->flags
;
4829 aname
->revision
= name
->revision
;
4830 aname
->hashalg
= name
->hash_alg
;
4831 aname
->versioncompat
= 1; /* SameMachine (default) */
4833 if (by_default_version
)
4834 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, name
->major
, name
->minor
, name
->build
, name
->revision
));
4837 if (absolute
!= NULL
&& *absolute
!= '\0') {
4838 const gchar
*prepend
= "file://";
4841 codebase
= g_strdup (absolute
);
4846 for (i
= strlen (codebase
) - 1; i
>= 0; i
--)
4847 if (codebase
[i
] == '\\')
4850 if (*codebase
== '/' && *(codebase
+ 1) == '/') {
4853 prepend
= "file:///";
4857 result
= g_strconcat (prepend
, codebase
, NULL
);
4863 MONO_OBJECT_SETREF (aname
, codebase
, mono_string_new (domain
, codebase
));
4867 if (!create_culture
) {
4868 MonoMethodDesc
*desc
= mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4869 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4870 g_assert (create_culture
);
4871 mono_method_desc_free (desc
);
4874 if (name
->culture
) {
4875 args
[0] = mono_string_new (domain
, name
->culture
);
4876 args
[1] = &assembly_ref
;
4877 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4880 if (name
->public_key
) {
4881 pkey_ptr
= (char*)name
->public_key
;
4882 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4884 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4885 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4886 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4887 } else if (default_publickey
) {
4888 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4889 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4892 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4893 if (name
->public_key_token
[0]) {
4897 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 8));
4898 p
= mono_array_addr (aname
->keyToken
, char, 0);
4900 for (i
= 0, j
= 0; i
< 8; i
++) {
4901 *p
= g_ascii_xdigit_value (name
->public_key_token
[j
++]) << 4;
4902 *p
|= g_ascii_xdigit_value (name
->public_key_token
[j
++]);
4905 } else if (default_token
) {
4906 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4911 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly
*assembly
)
4913 MonoDomain
*domain
= mono_object_domain (assembly
);
4914 MonoAssembly
*mass
= assembly
->assembly
;
4918 name
= g_strdup_printf (
4919 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4921 mass
->aname
.major
, mass
->aname
.minor
, mass
->aname
.build
, mass
->aname
.revision
,
4922 mass
->aname
.culture
&& *mass
->aname
.culture
? mass
->aname
.culture
: "neutral",
4923 mass
->aname
.public_key_token
[0] ? (char *)mass
->aname
.public_key_token
: "null",
4924 (mass
->aname
.flags
& ASSEMBLYREF_RETARGETABLE_FLAG
) ? ", Retargetable=Yes" : "");
4926 res
= mono_string_new (domain
, name
);
4933 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly
*assembly
, MonoReflectionAssemblyName
*aname
)
4936 MonoAssembly
*mass
= assembly
->assembly
;
4938 MONO_ARCH_SAVE_REGS
;
4940 if (g_path_is_absolute (mass
->image
->name
)) {
4941 fill_reflection_assembly_name (mono_object_domain (assembly
),
4942 aname
, &mass
->aname
, mass
->image
->name
, TRUE
,
4946 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4948 fill_reflection_assembly_name (mono_object_domain (assembly
),
4949 aname
, &mass
->aname
, absolute
, TRUE
, TRUE
,
4956 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString
*fname
, MonoReflectionAssemblyName
*aname
)
4959 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
4962 MonoAssemblyName name
;
4965 MONO_ARCH_SAVE_REGS
;
4967 filename
= mono_string_to_utf8 (fname
);
4969 dirname
= g_path_get_dirname (filename
);
4970 replace_shadow_path (mono_domain_get (), dirname
, &filename
);
4973 image
= mono_image_open (filename
, &status
);
4979 if (status
== MONO_IMAGE_IMAGE_INVALID
)
4980 exc
= mono_get_exception_bad_image_format2 (NULL
, fname
);
4982 exc
= mono_get_exception_file_not_found2 (NULL
, fname
);
4983 mono_raise_exception (exc
);
4986 res
= mono_assembly_fill_assembly_name (image
, &name
);
4988 mono_image_close (image
);
4990 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4993 fill_reflection_assembly_name (mono_domain_get (), aname
, &name
, filename
,
4997 mono_image_close (image
);
5001 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly
*assembly
,
5002 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
)
5004 MonoBoolean result
= FALSE
;
5005 MonoDeclSecurityEntry entry
;
5007 /* SecurityAction.RequestMinimum */
5008 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5009 *minimum
= entry
.blob
;
5010 *minLength
= entry
.size
;
5013 /* SecurityAction.RequestOptional */
5014 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5015 *optional
= entry
.blob
;
5016 *optLength
= entry
.size
;
5019 /* SecurityAction.RequestRefuse */
5020 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5021 *refused
= entry
.blob
;
5022 *refLength
= entry
.size
;
5030 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArray
**exceptions
, MonoBoolean exportedOnly
)
5034 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5036 guint32 attrs
, visibility
;
5038 /* we start the count from 1 because we skip the special type <Module> */
5041 for (i
= 1; i
< tdef
->rows
; ++i
) {
5042 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5043 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5044 if (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5048 count
= tdef
->rows
- 1;
5050 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
5051 *exceptions
= mono_array_new (domain
, mono_defaults
.exception_class
, count
);
5053 for (i
= 1; i
< tdef
->rows
; ++i
) {
5054 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5055 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5056 if (!exportedOnly
|| (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)) {
5057 klass
= mono_class_get (image
, (i
+ 1) | MONO_TOKEN_TYPE_DEF
);
5059 mono_array_setref (res
, count
, mono_type_get_object (domain
, &klass
->byval_arg
));
5061 MonoLoaderError
*error
;
5064 error
= mono_loader_get_last_error ();
5065 g_assert (error
!= NULL
);
5067 ex
= mono_loader_error_prepare_exception (error
);
5068 mono_array_setref (*exceptions
, count
, ex
);
5070 if (mono_loader_get_last_error ())
5071 mono_loader_clear_error ();
5080 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly
*assembly
, MonoBoolean exportedOnly
)
5082 MonoArray
*res
= NULL
;
5083 MonoArray
*exceptions
= NULL
;
5084 MonoImage
*image
= NULL
;
5085 MonoTableInfo
*table
= NULL
;
5088 int i
, len
, ex_count
;
5090 MONO_ARCH_SAVE_REGS
;
5092 domain
= mono_object_domain (assembly
);
5094 g_assert (!assembly
->assembly
->dynamic
);
5095 image
= assembly
->assembly
->image
;
5096 table
= &image
->tables
[MONO_TABLE_FILE
];
5097 res
= mono_module_get_types (domain
, image
, &exceptions
, exportedOnly
);
5099 /* Append data from all modules in the assembly */
5100 for (i
= 0; i
< table
->rows
; ++i
) {
5101 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5102 MonoImage
*loaded_image
= mono_assembly_load_module (image
->assembly
, i
+ 1);
5105 MonoArray
*res2
= mono_module_get_types (domain
, loaded_image
, &ex2
, exportedOnly
);
5106 /* Append the new types to the end of the array */
5107 if (mono_array_length (res2
) > 0) {
5109 MonoArray
*res3
, *ex3
;
5111 len1
= mono_array_length (res
);
5112 len2
= mono_array_length (res2
);
5114 res3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5115 mono_array_memcpy_refs (res3
, 0, res
, 0, len1
);
5116 mono_array_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5119 ex3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5120 mono_array_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5121 mono_array_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5128 /* the ReflectionTypeLoadException must have all the types (Types property),
5129 * NULL replacing types which throws an exception. The LoaderException must
5130 * contain all exceptions for NULL items.
5133 len
= mono_array_length (res
);
5136 for (i
= 0; i
< len
; i
++) {
5137 MonoReflectionType
*t
= mono_array_get (res
, gpointer
, i
);
5141 klass
= mono_type_get_class (t
->type
);
5142 if ((klass
!= NULL
) && klass
->exception_type
) {
5143 /* keep the class in the list */
5144 list
= g_list_append (list
, klass
);
5145 /* and replace Type with NULL */
5146 mono_array_setref (res
, i
, NULL
);
5153 if (list
|| ex_count
) {
5155 MonoException
*exc
= NULL
;
5156 MonoArray
*exl
= NULL
;
5157 int j
, length
= g_list_length (list
) + ex_count
;
5159 mono_loader_clear_error ();
5161 exl
= mono_array_new (domain
, mono_defaults
.exception_class
, length
);
5162 /* Types for which mono_class_get () succeeded */
5163 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5164 MonoException
*exc
= mono_class_get_exception_for_failure (tmp
->data
);
5165 mono_array_setref (exl
, i
, exc
);
5167 /* Types for which it don't */
5168 for (j
= 0; j
< mono_array_length (exceptions
); ++j
) {
5169 MonoException
*exc
= mono_array_get (exceptions
, MonoException
*, j
);
5171 g_assert (i
< length
);
5172 mono_array_setref (exl
, i
, exc
);
5179 exc
= mono_get_exception_reflection_type_load (res
, exl
);
5180 mono_loader_clear_error ();
5181 mono_raise_exception (exc
);
5188 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName
*name
, MonoString
*assname
)
5190 MonoAssemblyName aname
;
5191 MonoDomain
*domain
= mono_object_domain (name
);
5193 gboolean is_version_defined
;
5194 gboolean is_token_defined
;
5196 aname
.public_key
= NULL
;
5197 val
= mono_string_to_utf8 (assname
);
5198 if (!mono_assembly_name_parse_full (val
, &aname
, TRUE
, &is_version_defined
, &is_token_defined
)) {
5199 g_free ((guint8
*) aname
.public_key
);
5204 fill_reflection_assembly_name (domain
, name
, &aname
, "", is_version_defined
,
5205 FALSE
, is_token_defined
);
5207 mono_assembly_name_free (&aname
);
5208 g_free ((guint8
*) aname
.public_key
);
5214 static MonoReflectionType
*
5215 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule
*module
)
5217 MonoDomain
*domain
= mono_object_domain (module
);
5220 MONO_ARCH_SAVE_REGS
;
5222 g_assert (module
->image
);
5224 if (module
->image
->dynamic
&& ((MonoDynamicImage
*)(module
->image
))->initial_image
)
5225 /* These images do not have a global type */
5228 klass
= mono_class_get (module
->image
, 1 | MONO_TOKEN_TYPE_DEF
);
5229 return mono_type_get_object (domain
, &klass
->byval_arg
);
5233 ves_icall_System_Reflection_Module_Close (MonoReflectionModule
*module
)
5235 /*if (module->image)
5236 mono_image_close (module->image);*/
5240 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule
*module
)
5242 MonoDomain
*domain
= mono_object_domain (module
);
5244 MONO_ARCH_SAVE_REGS
;
5246 g_assert (module
->image
);
5247 return mono_string_new (domain
, module
->image
->guid
);
5251 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule
*module
)
5254 if (module
->image
&& module
->image
->is_module_handle
)
5255 return module
->image
->raw_data
;
5258 return (gpointer
) (-1);
5262 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
)
5264 if (image
->dynamic
) {
5265 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5266 *pe_kind
= dyn
->pe_kind
;
5267 *machine
= dyn
->machine
;
5270 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5271 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5276 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
)
5278 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5282 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule
*module
)
5284 MonoArray
*exceptions
;
5287 MONO_ARCH_SAVE_REGS
;
5290 return mono_array_new (mono_object_domain (module
), mono_defaults
.monotype_class
, 0);
5292 MonoArray
*res
= mono_module_get_types (mono_object_domain (module
), module
->image
, &exceptions
, FALSE
);
5293 for (i
= 0; i
< mono_array_length (exceptions
); ++i
) {
5294 MonoException
*ex
= mono_array_get (exceptions
, MonoException
*, i
);
5296 mono_raise_exception (ex
);
5303 mono_metadata_memberref_is_method (MonoImage
*image
, guint32 token
)
5305 guint32 cols
[MONO_MEMBERREF_SIZE
];
5307 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5308 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5309 mono_metadata_decode_blob_size (sig
, &sig
);
5310 return (*sig
!= 0x6);
5314 init_generic_context_from_args (MonoGenericContext
*context
, MonoArray
*type_args
, MonoArray
*method_args
)
5317 context
->class_inst
= mono_metadata_get_generic_inst (mono_array_length (type_args
),
5318 mono_array_addr (type_args
, MonoType
*, 0));
5320 context
->class_inst
= NULL
;
5322 context
->method_inst
= mono_metadata_get_generic_inst (mono_array_length (method_args
),
5323 mono_array_addr (method_args
, MonoType
*, 0));
5325 context
->method_inst
= NULL
;
5329 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5332 int table
= mono_metadata_token_table (token
);
5333 int index
= mono_metadata_token_index (token
);
5334 MonoGenericContext context
;
5336 *error
= ResolveTokenError_Other
;
5338 /* Validate token */
5339 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5340 (table
!= MONO_TABLE_TYPESPEC
)) {
5341 *error
= ResolveTokenError_BadTable
;
5345 if (image
->dynamic
) {
5346 if (type_args
|| method_args
)
5347 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5348 klass
= mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5351 return &klass
->byval_arg
;
5354 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5355 *error
= ResolveTokenError_OutOfRange
;
5359 init_generic_context_from_args (&context
, type_args
, method_args
);
5360 klass
= mono_class_get_full (image
, token
, &context
);
5362 if (mono_loader_get_last_error ())
5363 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5366 return &klass
->byval_arg
;
5372 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5374 int table
= mono_metadata_token_table (token
);
5375 int index
= mono_metadata_token_index (token
);
5376 MonoGenericContext context
;
5379 *error
= ResolveTokenError_Other
;
5381 /* Validate token */
5382 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5383 (table
!= MONO_TABLE_MEMBERREF
)) {
5384 *error
= ResolveTokenError_BadTable
;
5388 if (image
->dynamic
) {
5389 if (type_args
|| method_args
)
5390 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5391 /* FIXME: validate memberref token type */
5392 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5395 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5396 *error
= ResolveTokenError_OutOfRange
;
5399 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_metadata_memberref_is_method (image
, token
))) {
5400 *error
= ResolveTokenError_BadTable
;
5404 init_generic_context_from_args (&context
, type_args
, method_args
);
5405 method
= mono_get_method_full (image
, token
, NULL
, &context
);
5407 if (mono_loader_get_last_error ())
5408 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5414 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5416 int index
= mono_metadata_token_index (token
);
5418 *error
= ResolveTokenError_Other
;
5420 /* Validate token */
5421 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5422 *error
= ResolveTokenError_BadTable
;
5427 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5429 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5430 *error
= ResolveTokenError_OutOfRange
;
5434 /* FIXME: What to do if the index points into the middle of a string ? */
5436 return mono_ldstr (mono_domain_get (), image
, index
);
5439 static MonoClassField
*
5440 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5443 int table
= mono_metadata_token_table (token
);
5444 int index
= mono_metadata_token_index (token
);
5445 MonoGenericContext context
;
5446 MonoClassField
*field
;
5448 *error
= ResolveTokenError_Other
;
5450 /* Validate token */
5451 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
5452 *error
= ResolveTokenError_BadTable
;
5456 if (image
->dynamic
) {
5457 if (type_args
|| method_args
)
5458 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5459 /* FIXME: validate memberref token type */
5460 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5463 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5464 *error
= ResolveTokenError_OutOfRange
;
5467 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_metadata_memberref_is_method (image
, token
))) {
5468 *error
= ResolveTokenError_BadTable
;
5472 init_generic_context_from_args (&context
, type_args
, method_args
);
5473 field
= mono_field_from_token (image
, token
, &klass
, &context
);
5475 if (mono_loader_get_last_error ())
5476 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5483 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5485 int table
= mono_metadata_token_table (token
);
5487 *error
= ResolveTokenError_Other
;
5490 case MONO_TABLE_TYPEDEF
:
5491 case MONO_TABLE_TYPEREF
:
5492 case MONO_TABLE_TYPESPEC
: {
5493 MonoType
*t
= ves_icall_System_Reflection_Module_ResolveTypeToken (image
, token
, type_args
, method_args
, error
);
5495 return (MonoObject
*)mono_type_get_object (mono_domain_get (), t
);
5499 case MONO_TABLE_METHOD
:
5500 case MONO_TABLE_METHODSPEC
: {
5501 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5503 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5507 case MONO_TABLE_FIELD
: {
5508 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5510 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5514 case MONO_TABLE_MEMBERREF
:
5515 if (mono_metadata_memberref_is_method (image
, token
)) {
5516 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5518 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5523 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5525 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5532 *error
= ResolveTokenError_BadTable
;
5539 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5541 int table
= mono_metadata_token_table (token
);
5542 int idx
= mono_metadata_token_index (token
);
5543 MonoTableInfo
*tables
= image
->tables
;
5548 *error
= ResolveTokenError_OutOfRange
;
5550 /* FIXME: Support other tables ? */
5551 if (table
!= MONO_TABLE_STANDALONESIG
)
5557 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
5560 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
5562 ptr
= mono_metadata_blob_heap (image
, sig
);
5563 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
5565 res
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, len
);
5566 memcpy (mono_array_addr (res
, guint8
, 0), ptr
, len
);
5570 static MonoReflectionType
*
5571 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder
*tb
, MonoString
*smodifiers
)
5574 int isbyref
= 0, rank
;
5575 char *str
= mono_string_to_utf8 (smodifiers
);
5578 MONO_ARCH_SAVE_REGS
;
5580 klass
= mono_class_from_mono_type (tb
->type
.type
);
5582 /* logic taken from mono_reflection_parse_type(): keep in sync */
5586 if (isbyref
) { /* only one level allowed by the spec */
5593 return mono_type_get_object (mono_object_domain (tb
), &klass
->this_arg
);
5596 klass
= mono_ptr_class_get (&klass
->byval_arg
);
5597 mono_class_init (klass
);
5608 else if (*p
!= '*') { /* '*' means unknown lower bound */
5619 klass
= mono_array_class_get (klass
, rank
);
5620 mono_class_init (klass
);
5627 return mono_type_get_object (mono_object_domain (tb
), &klass
->byval_arg
);
5631 ves_icall_Type_IsArrayImpl (MonoReflectionType
*t
)
5636 MONO_ARCH_SAVE_REGS
;
5639 res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
5644 static MonoReflectionType
*
5645 ves_icall_Type_make_array_type (MonoReflectionType
*type
, int rank
)
5647 MonoClass
*klass
, *aklass
;
5649 MONO_ARCH_SAVE_REGS
;
5651 klass
= mono_class_from_mono_type (type
->type
);
5652 if (rank
== 0) //single dimentional array
5653 aklass
= mono_array_class_get (klass
, 1);
5655 aklass
= mono_bounded_array_class_get (klass
, rank
, TRUE
);
5657 return mono_type_get_object (mono_object_domain (type
), &aklass
->byval_arg
);
5660 static MonoReflectionType
*
5661 ves_icall_Type_make_byref_type (MonoReflectionType
*type
)
5665 MONO_ARCH_SAVE_REGS
;
5667 klass
= mono_class_from_mono_type (type
->type
);
5669 return mono_type_get_object (mono_object_domain (type
), &klass
->this_arg
);
5672 static MonoReflectionType
*
5673 ves_icall_Type_MakePointerType (MonoReflectionType
*type
)
5677 MONO_ARCH_SAVE_REGS
;
5679 pklass
= mono_ptr_class_get (type
->type
);
5681 return mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
);
5685 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType
*type
, MonoObject
*target
,
5686 MonoReflectionMethod
*info
, MonoBoolean throwOnBindFailure
)
5688 MonoClass
*delegate_class
= mono_class_from_mono_type (type
->type
);
5689 MonoObject
*delegate
;
5691 MonoMethod
*method
= info
->method
;
5693 MONO_ARCH_SAVE_REGS
;
5695 mono_assert (delegate_class
->parent
== mono_defaults
.multicastdelegate_class
);
5697 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
) {
5698 if (!mono_security_core_clr_ensure_delegate_creation (method
, throwOnBindFailure
))
5702 delegate
= mono_object_new (mono_object_domain (type
), delegate_class
);
5704 if (method
->dynamic
) {
5705 /* Creating a trampoline would leak memory */
5706 func
= mono_compile_method (method
);
5708 func
= mono_create_ftnptr (mono_domain_get (),
5709 mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
));
5712 mono_delegate_ctor_with_method (delegate
, target
, func
, method
);
5718 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate
*this)
5720 /* Reset the invoke impl to the default one */
5721 this->invoke_impl
= mono_runtime_create_delegate_trampoline (this->object
.vtable
->klass
);
5725 * Magic number to convert a time which is relative to
5726 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5728 #define EPOCH_ADJUST ((guint64)62135596800LL)
5731 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5733 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5736 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5738 convert_to_absolute_date(SYSTEMTIME
*date
)
5740 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5741 static int days_in_month
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5742 static int leap_days_in_month
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5743 /* from the calendar FAQ */
5744 int a
= (14 - date
->wMonth
) / 12;
5745 int y
= date
->wYear
- a
;
5746 int m
= date
->wMonth
+ 12 * a
- 2;
5747 int d
= (1 + y
+ y
/4 - y
/100 + y
/400 + (31*m
)/12) % 7;
5749 /* d is now the day of the week for the first of the month (0 == Sunday) */
5751 int day_of_week
= date
->wDayOfWeek
;
5753 /* set day_in_month to the first day in the month which falls on day_of_week */
5754 int day_in_month
= 1 + (day_of_week
- d
);
5755 if (day_in_month
<= 0)
5758 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5759 date
->wDay
= day_in_month
+ (date
->wDay
- 1) * 7;
5760 if (date
->wDay
> (IS_LEAP(date
->wYear
) ? leap_days_in_month
[date
->wMonth
- 1] : days_in_month
[date
->wMonth
- 1]))
5767 * Return's the offset from GMT of a local time.
5769 * tm is a local time
5770 * t is the same local time as seconds.
5773 gmt_offset(struct tm
*tm
, time_t t
)
5775 #if defined (HAVE_TM_GMTOFF)
5776 return tm
->tm_gmtoff
;
5781 g
.tm_isdst
= tm
->tm_isdst
;
5783 return (int)difftime(t
, t2
);
5788 * This is heavily based on zdump.c from glibc 2.2.
5790 * * data[0]: start of daylight saving time (in DateTime ticks).
5791 * * data[1]: end of daylight saving time (in DateTime ticks).
5792 * * data[2]: utcoffset (in TimeSpan ticks).
5793 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5794 * * name[0]: name of this timezone when not daylight saving.
5795 * * name[1]: name of this timezone when daylight saving.
5797 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5798 * the class library allows years between 1 and 9999.
5800 * Returns true on success and zero on failure.
5803 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year
, MonoArray
**data
, MonoArray
**names
)
5806 MonoDomain
*domain
= mono_domain_get ();
5807 struct tm start
, tt
;
5811 int is_daylight
= 0, day
;
5814 MONO_ARCH_SAVE_REGS
;
5816 MONO_CHECK_ARG_NULL (data
);
5817 MONO_CHECK_ARG_NULL (names
);
5819 mono_gc_wbarrier_generic_store (data
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5820 mono_gc_wbarrier_generic_store (names
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.string_class
, 2));
5823 * no info is better than crashing: we'll need our own tz data
5824 * to make this work properly, anyway. The range is probably
5825 * reduced to 1970 .. 2037 because that is what mktime is
5826 * guaranteed to support (we get into an infinite loop
5830 memset (&start
, 0, sizeof (start
));
5833 start
.tm_year
= year
-1900;
5835 t
= mktime (&start
);
5837 if ((year
< 1970) || (year
> 2037) || (t
== -1)) {
5839 tt
= *localtime (&t
);
5840 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5841 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5842 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5846 gmtoff
= gmt_offset (&start
, t
);
5848 /* For each day of the year, calculate the tm_gmtoff. */
5849 for (day
= 0; day
< 365; day
++) {
5852 tt
= *localtime (&t
);
5854 /* Daylight saving starts or ends here. */
5855 if (gmt_offset (&tt
, t
) != gmtoff
) {
5859 /* Try to find the exact hour when daylight saving starts/ends. */
5863 tt1
= *localtime (&t1
);
5864 } while (gmt_offset (&tt1
, t1
) != gmtoff
);
5866 /* Try to find the exact minute when daylight saving starts/ends. */
5869 tt1
= *localtime (&t1
);
5870 } while (gmt_offset (&tt1
, t1
) == gmtoff
);
5872 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5874 /* Write data, if we're already in daylight saving, we're done. */
5876 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5877 mono_array_set ((*data
), gint64
, 1, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5880 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5881 mono_array_set ((*data
), gint64
, 0, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5885 /* This is only set once when we enter daylight saving. */
5886 mono_array_set ((*data
), gint64
, 2, (gint64
)gmtoff
* 10000000L);
5887 mono_array_set ((*data
), gint64
, 3, (gint64
)(gmt_offset (&tt
, t
) - gmtoff
) * 10000000L);
5889 gmtoff
= gmt_offset (&tt
, t
);
5894 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5895 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5896 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5897 mono_array_set ((*data
), gint64
, 0, 0);
5898 mono_array_set ((*data
), gint64
, 1, 0);
5899 mono_array_set ((*data
), gint64
, 2, (gint64
) gmtoff
* 10000000L);
5900 mono_array_set ((*data
), gint64
, 3, 0);
5905 MonoDomain
*domain
= mono_domain_get ();
5906 TIME_ZONE_INFORMATION tz_info
;
5911 tz_id
= GetTimeZoneInformation (&tz_info
);
5912 if (tz_id
== TIME_ZONE_ID_INVALID
)
5915 MONO_CHECK_ARG_NULL (data
);
5916 MONO_CHECK_ARG_NULL (names
);
5918 mono_gc_wbarrier_generic_store (data
, mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5919 mono_gc_wbarrier_generic_store (names
, mono_array_new (domain
, mono_defaults
.string_class
, 2));
5921 for (i
= 0; i
< 32; ++i
)
5922 if (!tz_info
.DaylightName
[i
])
5924 mono_array_setref ((*names
), 1, mono_string_new_utf16 (domain
, tz_info
.DaylightName
, i
));
5925 for (i
= 0; i
< 32; ++i
)
5926 if (!tz_info
.StandardName
[i
])
5928 mono_array_setref ((*names
), 0, mono_string_new_utf16 (domain
, tz_info
.StandardName
, i
));
5930 if ((year
<= 1601) || (year
> 30827)) {
5932 * According to MSDN, the MS time functions can't handle dates outside
5938 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5939 if (tz_id
!= TIME_ZONE_ID_UNKNOWN
) {
5940 tz_info
.StandardDate
.wYear
= year
;
5941 convert_to_absolute_date(&tz_info
.StandardDate
);
5942 err
= SystemTimeToFileTime (&tz_info
.StandardDate
, &ft
);
5947 mono_array_set ((*data
), gint64
, 1, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
5948 tz_info
.DaylightDate
.wYear
= year
;
5949 convert_to_absolute_date(&tz_info
.DaylightDate
);
5950 err
= SystemTimeToFileTime (&tz_info
.DaylightDate
, &ft
);
5955 mono_array_set ((*data
), gint64
, 0, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
5957 mono_array_set ((*data
), gint64
, 2, (tz_info
.Bias
+ tz_info
.StandardBias
) * -600000000LL);
5958 mono_array_set ((*data
), gint64
, 3, (tz_info
.DaylightBias
- tz_info
.StandardBias
) * -600000000LL);
5965 ves_icall_System_Object_obj_address (MonoObject
*this)
5967 MONO_ARCH_SAVE_REGS
;
5974 static inline gint32
5975 mono_array_get_byte_length (MonoArray
*array
)
5981 klass
= array
->obj
.vtable
->klass
;
5983 if (array
->bounds
== NULL
)
5984 length
= array
->max_length
;
5987 for (i
= 0; i
< klass
->rank
; ++ i
)
5988 length
*= array
->bounds
[i
].length
;
5991 switch (klass
->element_class
->byval_arg
.type
) {
5994 case MONO_TYPE_BOOLEAN
:
5998 case MONO_TYPE_CHAR
:
6006 return length
* sizeof (gpointer
);
6017 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6019 MONO_ARCH_SAVE_REGS
;
6021 return mono_array_get_byte_length (array
);
6025 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6027 MONO_ARCH_SAVE_REGS
;
6029 return mono_array_get (array
, gint8
, idx
);
6033 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6035 MONO_ARCH_SAVE_REGS
;
6037 mono_array_set (array
, gint8
, idx
, value
);
6041 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6043 guint8
*src_buf
, *dest_buf
;
6045 MONO_ARCH_SAVE_REGS
;
6047 /* watch out for integer overflow */
6048 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6051 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6052 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6055 memcpy (dest_buf
, src_buf
, count
);
6057 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6063 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject
*this, MonoString
*class_name
)
6065 MonoDomain
*domain
= mono_object_domain (this);
6067 MonoRealProxy
*rp
= ((MonoRealProxy
*)this);
6068 MonoTransparentProxy
*tp
;
6072 MONO_ARCH_SAVE_REGS
;
6074 res
= mono_object_new (domain
, mono_defaults
.transparent_proxy_class
);
6075 tp
= (MonoTransparentProxy
*) res
;
6077 MONO_OBJECT_SETREF (tp
, rp
, rp
);
6078 type
= ((MonoReflectionType
*)rp
->class_to_proxy
)->type
;
6079 klass
= mono_class_from_mono_type (type
);
6081 tp
->custom_type_info
= (mono_object_isinst (this, mono_defaults
.iremotingtypeinfo_class
) != NULL
);
6082 tp
->remote_class
= mono_remote_class (domain
, class_name
, klass
);
6084 res
->vtable
= mono_remote_class_vtable (domain
, tp
->remote_class
, rp
);
6088 static MonoReflectionType
*
6089 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6091 return mono_type_get_object (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
);
6094 /* System.Environment */
6097 ves_icall_System_Environment_get_UserName (void)
6099 MONO_ARCH_SAVE_REGS
;
6101 /* using glib is more portable */
6102 return mono_string_new (mono_domain_get (), g_get_user_name ());
6107 ves_icall_System_Environment_get_MachineName (void)
6109 #if defined (HOST_WIN32)
6114 len
= MAX_COMPUTERNAME_LENGTH
+ 1;
6115 buf
= g_new (gunichar2
, len
);
6118 if (GetComputerName (buf
, (PDWORD
) &len
))
6119 result
= mono_string_new_utf16 (mono_domain_get (), buf
, len
);
6123 #elif !defined(DISABLE_SOCKETS)
6127 if (gethostname (buf
, sizeof (buf
)) == 0)
6128 result
= mono_string_new (mono_domain_get (), buf
);
6134 return mono_string_new (mono_domain_get (), "mono");
6139 ves_icall_System_Environment_get_Platform (void)
6141 #if defined (TARGET_WIN32)
6144 #elif defined(__MACH__)
6147 // For compatibility with our client code, this will be 4 for a while.
6148 // We will eventually move to 6 to match .NET, but it requires all client
6149 // code to be updated and the documentation everywhere to be updated
6160 ves_icall_System_Environment_get_NewLine (void)
6162 MONO_ARCH_SAVE_REGS
;
6164 #if defined (HOST_WIN32)
6165 return mono_string_new (mono_domain_get (), "\r\n");
6167 return mono_string_new (mono_domain_get (), "\n");
6172 ves_icall_System_Environment_GetEnvironmentVariable (MonoString
*name
)
6177 MONO_ARCH_SAVE_REGS
;
6182 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6183 value
= g_getenv (utf8_name
);
6190 return mono_string_new (mono_domain_get (), value
);
6194 * There is no standard way to get at environ.
6197 #ifndef __MINGW32_VERSION
6199 /* Apple defines this in crt_externs.h but doesn't provide that header for
6200 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6201 * in fact exist on all implementations (so far)
6203 gchar
***_NSGetEnviron(void);
6204 #define environ (*_NSGetEnviron())
6213 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6224 env_strings
= GetEnvironmentStrings();
6227 env_string
= env_strings
;
6228 while (*env_string
!= '\0') {
6229 /* weird case that MS seems to skip */
6230 if (*env_string
!= '=')
6232 while (*env_string
!= '\0')
6238 domain
= mono_domain_get ();
6239 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6243 env_string
= env_strings
;
6244 while (*env_string
!= '\0') {
6245 /* weird case that MS seems to skip */
6246 if (*env_string
!= '=') {
6247 equal_str
= wcschr(env_string
, '=');
6248 g_assert(equal_str
);
6249 str
= mono_string_new_utf16 (domain
, env_string
, equal_str
-env_string
);
6250 mono_array_setref (names
, n
, str
);
6253 while (*env_string
!= '\0')
6258 FreeEnvironmentStrings (env_strings
);
6270 MONO_ARCH_SAVE_REGS
;
6273 for (e
= environ
; *e
!= 0; ++ e
)
6276 domain
= mono_domain_get ();
6277 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6280 for (e
= environ
; *e
!= 0; ++ e
) {
6281 parts
= g_strsplit (*e
, "=", 2);
6283 str
= mono_string_new (domain
, *parts
);
6284 mono_array_setref (names
, n
, str
);
6297 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6299 #if !GLIB_CHECK_VERSION(2,4,0)
6300 #define g_setenv(a,b,c) setenv(a,b,c)
6301 #define g_unsetenv(a) unsetenv(a)
6305 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6310 gunichar2
*utf16_name
, *utf16_value
;
6312 gchar
*utf8_name
, *utf8_value
;
6315 MONO_ARCH_SAVE_REGS
;
6318 utf16_name
= mono_string_to_utf16 (name
);
6319 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6320 SetEnvironmentVariable (utf16_name
, NULL
);
6321 g_free (utf16_name
);
6325 utf16_value
= mono_string_to_utf16 (value
);
6327 SetEnvironmentVariable (utf16_name
, utf16_value
);
6329 g_free (utf16_name
);
6330 g_free (utf16_value
);
6332 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6334 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6335 g_unsetenv (utf8_name
);
6340 utf8_value
= mono_string_to_utf8_checked (value
, &error
);
6341 if (!mono_error_ok (&error
)) {
6343 mono_error_raise_exception (&error
);
6345 g_setenv (utf8_name
, utf8_value
, TRUE
);
6348 g_free (utf8_value
);
6353 ves_icall_System_Environment_Exit (int result
)
6355 MONO_ARCH_SAVE_REGS
;
6357 mono_threads_set_shutting_down ();
6359 mono_runtime_set_shutting_down ();
6361 /* This will kill the tp threads which cannot be suspended */
6362 mono_thread_pool_cleanup ();
6364 /* Suspend all managed threads since the runtime is going away */
6365 mono_thread_suspend_all_other_threads ();
6367 mono_runtime_quit ();
6369 /* we may need to do some cleanup here... */
6374 ves_icall_System_Environment_GetGacPath (void)
6376 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6380 ves_icall_System_Environment_GetWindowsFolderPath (int folder
)
6382 #if defined (HOST_WIN32)
6383 #ifndef CSIDL_FLAG_CREATE
6384 #define CSIDL_FLAG_CREATE 0x8000
6387 WCHAR path
[MAX_PATH
];
6388 /* Create directory if no existing */
6389 if (SUCCEEDED (SHGetFolderPathW (NULL
, folder
| CSIDL_FLAG_CREATE
, NULL
, 0, path
))) {
6393 return mono_string_new_utf16 (mono_domain_get (), path
, len
);
6396 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6398 return mono_string_new (mono_domain_get (), "");
6402 ves_icall_System_Environment_GetLogicalDrives (void)
6404 gunichar2 buf
[128], *ptr
, *dname
;
6406 guint initial_size
= 127, size
= 128;
6409 MonoString
*drivestr
;
6410 MonoDomain
*domain
= mono_domain_get ();
6413 MONO_ARCH_SAVE_REGS
;
6418 while (size
> initial_size
) {
6419 size
= (guint
) GetLogicalDriveStrings (initial_size
, ptr
);
6420 if (size
> initial_size
) {
6423 ptr
= g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6424 initial_size
= size
;
6438 result
= mono_array_new (domain
, mono_defaults
.string_class
, ndrives
);
6443 while (*u16
) { u16
++; len
++; }
6444 drivestr
= mono_string_new_utf16 (domain
, dname
, len
);
6445 mono_array_setref (result
, ndrives
++, drivestr
);
6456 ves_icall_System_Environment_InternalGetHome (void)
6458 MONO_ARCH_SAVE_REGS
;
6460 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6463 static const char *encodings
[] = {
6465 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6466 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6467 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6469 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6470 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6471 "x_unicode_2_0_utf_7",
6473 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6474 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6476 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6479 "unicodefffe", "utf_16be",
6486 * Returns the internal codepage, if the value of "int_code_page" is
6487 * 1 at entry, and we can not compute a suitable code page number,
6488 * returns the code page as a string
6491 ves_icall_System_Text_Encoding_InternalCodePage (gint32
*int_code_page
)
6496 char *codepage
= NULL
;
6498 int want_name
= *int_code_page
;
6501 *int_code_page
= -1;
6502 MONO_ARCH_SAVE_REGS
;
6504 g_get_charset (&cset
);
6505 c
= codepage
= strdup (cset
);
6506 for (c
= codepage
; *c
; c
++){
6507 if (isascii (*c
) && isalpha (*c
))
6512 /* g_print ("charset: %s\n", cset); */
6514 /* handle some common aliases */
6517 for (i
= 0; p
!= 0; ){
6518 if ((gssize
) p
< 7){
6520 p
= encodings
[++i
];
6523 if (strcmp (p
, codepage
) == 0){
6524 *int_code_page
= code
;
6527 p
= encodings
[++i
];
6530 if (strstr (codepage
, "utf_8") != NULL
)
6531 *int_code_page
|= 0x10000000;
6534 if (want_name
&& *int_code_page
== -1)
6535 return mono_string_new (mono_domain_get (), cset
);
6541 ves_icall_System_Environment_get_HasShutdownStarted (void)
6543 if (mono_runtime_is_shutting_down ())
6546 if (mono_domain_is_unloading (mono_domain_get ()))
6553 ves_icall_System_Environment_BroadcastSettingChange (void)
6556 SendMessageTimeout (HWND_BROADCAST
, WM_SETTINGCHANGE
, NULL
, L
"Environment", SMTO_ABORTIFHUNG
, 2000, 0);
6561 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage
*this,
6562 MonoReflectionMethod
*method
,
6563 MonoArray
*out_args
)
6565 MONO_ARCH_SAVE_REGS
;
6567 mono_message_init (mono_object_domain (this), this, method
, out_args
);
6571 ves_icall_IsTransparentProxy (MonoObject
*proxy
)
6573 MONO_ARCH_SAVE_REGS
;
6578 if (proxy
->vtable
->klass
== mono_defaults
.transparent_proxy_class
)
6584 static MonoReflectionMethod
*
6585 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6586 MonoReflectionType
*rtype
, MonoReflectionMethod
*rmethod
)
6590 MonoMethod
**vtable
;
6591 MonoMethod
*res
= NULL
;
6593 MONO_CHECK_ARG_NULL (rtype
);
6594 MONO_CHECK_ARG_NULL (rmethod
);
6596 method
= rmethod
->method
;
6597 klass
= mono_class_from_mono_type (rtype
->type
);
6599 if (MONO_CLASS_IS_INTERFACE (klass
))
6602 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
6605 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
6606 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
6612 mono_class_setup_vtable (klass
);
6613 vtable
= klass
->vtable
;
6615 if (method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
) {
6616 gboolean variance_used
= FALSE
;
6617 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6618 int offs
= mono_class_interface_offset_with_variance (klass
, method
->klass
, &variance_used
);
6620 res
= vtable
[offs
+ method
->slot
];
6622 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
6625 if (method
->slot
!= -1)
6626 res
= vtable
[method
->slot
];
6632 return mono_method_get_object (mono_domain_get (), res
, NULL
);
6636 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType
*type
, MonoBoolean enable
)
6641 MONO_ARCH_SAVE_REGS
;
6643 klass
= mono_class_from_mono_type (type
->type
);
6644 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, TRUE
);
6646 if (enable
) vtable
->remote
= 1;
6647 else vtable
->remote
= 0;
6651 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType
*type
)
6656 MONO_ARCH_SAVE_REGS
;
6658 domain
= mono_object_domain (type
);
6659 klass
= mono_class_from_mono_type (type
->type
);
6661 if (klass
->rank
>= 1) {
6662 g_assert (klass
->rank
== 1);
6663 return (MonoObject
*) mono_array_new (domain
, klass
->element_class
, 0);
6665 /* Bypass remoting object creation check */
6666 return mono_object_new_alloc_specific (mono_class_vtable_full (domain
, klass
, TRUE
));
6671 ves_icall_System_IO_get_temp_path (void)
6673 MONO_ARCH_SAVE_REGS
;
6675 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6678 #ifndef PLATFORM_NO_DRIVEINFO
6680 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString
*path_name
, guint64
*free_bytes_avail
,
6681 guint64
*total_number_of_bytes
, guint64
*total_number_of_free_bytes
,
6685 ULARGE_INTEGER wapi_free_bytes_avail
;
6686 ULARGE_INTEGER wapi_total_number_of_bytes
;
6687 ULARGE_INTEGER wapi_total_number_of_free_bytes
;
6689 MONO_ARCH_SAVE_REGS
;
6691 *error
= ERROR_SUCCESS
;
6692 result
= GetDiskFreeSpaceEx (mono_string_chars (path_name
), &wapi_free_bytes_avail
, &wapi_total_number_of_bytes
,
6693 &wapi_total_number_of_free_bytes
);
6696 *free_bytes_avail
= wapi_free_bytes_avail
.QuadPart
;
6697 *total_number_of_bytes
= wapi_total_number_of_bytes
.QuadPart
;
6698 *total_number_of_free_bytes
= wapi_total_number_of_free_bytes
.QuadPart
;
6700 *free_bytes_avail
= 0;
6701 *total_number_of_bytes
= 0;
6702 *total_number_of_free_bytes
= 0;
6703 *error
= GetLastError ();
6710 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString
*root_path_name
)
6712 MONO_ARCH_SAVE_REGS
;
6714 return GetDriveType (mono_string_chars (root_path_name
));
6719 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod
*method
)
6721 MONO_ARCH_SAVE_REGS
;
6723 return mono_compile_method (method
);
6727 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6732 MONO_ARCH_SAVE_REGS
;
6734 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
6736 #if defined (HOST_WIN32)
6737 /* Avoid mixing '/' and '\\' */
6740 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6741 if (path
[i
] == '/')
6745 mcpath
= mono_string_new (mono_domain_get (), path
);
6752 get_bundled_machine_config (void)
6754 const gchar
*machine_config
;
6756 MONO_ARCH_SAVE_REGS
;
6758 machine_config
= mono_get_machine_config ();
6760 if (!machine_config
)
6763 return mono_string_new (mono_domain_get (), machine_config
);
6767 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6772 MONO_ARCH_SAVE_REGS
;
6774 path
= g_path_get_dirname (mono_get_config_dir ());
6776 #if defined (HOST_WIN32)
6777 /* Avoid mixing '/' and '\\' */
6780 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6781 if (path
[i
] == '/')
6785 ipath
= mono_string_new (mono_domain_get (), path
);
6792 ves_icall_get_resources_ptr (MonoReflectionAssembly
*assembly
, gpointer
*result
, gint32
*size
)
6794 MonoPEResourceDataEntry
*entry
;
6797 MONO_ARCH_SAVE_REGS
;
6799 if (!assembly
|| !result
|| !size
)
6804 image
= assembly
->assembly
->image
;
6805 entry
= mono_image_lookup_resource (image
, MONO_PE_RESOURCE_ID_ASPNET_STRING
, 0, NULL
);
6809 *result
= mono_image_rva_map (image
, entry
->rde_data_offset
);
6814 *size
= entry
->rde_size
;
6820 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
6822 return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
6826 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
6828 #if defined (HOST_WIN32)
6829 OutputDebugString (mono_string_chars (message
));
6831 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
6835 /* Only used for value types */
6837 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType
*type
)
6842 MONO_ARCH_SAVE_REGS
;
6844 domain
= mono_object_domain (type
);
6845 klass
= mono_class_from_mono_type (type
->type
);
6847 if (mono_class_is_nullable (klass
))
6848 /* No arguments -> null */
6851 return mono_object_new (domain
, klass
);
6854 static MonoReflectionMethod
*
6855 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod
*m
, gboolean definition
)
6857 MonoClass
*klass
, *parent
;
6858 MonoMethod
*method
= m
->method
;
6859 MonoMethod
*result
= NULL
;
6861 MONO_ARCH_SAVE_REGS
;
6863 if (method
->klass
== NULL
)
6866 if (!(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
) ||
6867 MONO_CLASS_IS_INTERFACE (method
->klass
) ||
6868 method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
)
6871 klass
= method
->klass
;
6872 if (klass
->generic_class
)
6873 klass
= klass
->generic_class
->container_class
;
6876 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6877 for (parent
= klass
->parent
; parent
!= NULL
; parent
= parent
->parent
) {
6878 mono_class_setup_vtable (parent
);
6879 if (parent
->vtable_size
<= method
->slot
)
6884 klass
= klass
->parent
;
6889 if (klass
== method
->klass
)
6892 result
= klass
->vtable
[method
->slot
];
6893 if (result
== NULL
) {
6894 /* It is an abstract method */
6895 gpointer iter
= NULL
;
6896 while ((result
= mono_class_get_methods (klass
, &iter
)))
6897 if (result
->slot
== method
->slot
)
6904 return mono_method_get_object (mono_domain_get (), result
, NULL
);
6908 ves_icall_MonoMethod_get_name (MonoReflectionMethod
*m
)
6910 MonoMethod
*method
= m
->method
;
6912 MONO_OBJECT_SETREF (m
, name
, mono_string_new (mono_object_domain (m
), method
->name
));
6917 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
6919 MONO_ARCH_SAVE_REGS
;
6921 iter
->sig
= *(MonoMethodSignature
**)argsp
;
6923 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
6924 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
6927 /* FIXME: it's not documented what start is exactly... */
6931 iter
->args
= argsp
+ sizeof (gpointer
);
6933 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
6935 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6939 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
6941 guint32 i
, arg_size
;
6944 MONO_ARCH_SAVE_REGS
;
6946 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
6948 g_assert (i
< iter
->sig
->param_count
);
6950 res
.type
= iter
->sig
->params
[i
];
6951 res
.klass
= mono_class_from_mono_type (res
.type
);
6952 res
.value
= iter
->args
;
6953 arg_size
= mono_type_stack_size (res
.type
, &align
);
6954 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
6955 if (arg_size
<= sizeof (gpointer
)) {
6957 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
6958 res
.value
= (guint8
*)res
.value
+ padding
;
6961 iter
->args
= (char*)iter
->args
+ arg_size
;
6964 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6970 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
6972 guint32 i
, arg_size
;
6975 MONO_ARCH_SAVE_REGS
;
6977 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
6979 g_assert (i
< iter
->sig
->param_count
);
6981 while (i
< iter
->sig
->param_count
) {
6982 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
6984 res
.type
= iter
->sig
->params
[i
];
6985 res
.klass
= mono_class_from_mono_type (res
.type
);
6986 /* FIXME: endianess issue... */
6987 res
.value
= iter
->args
;
6988 arg_size
= mono_type_stack_size (res
.type
, &align
);
6989 iter
->args
= (char*)iter
->args
+ arg_size
;
6991 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6994 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7003 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7006 MONO_ARCH_SAVE_REGS
;
7008 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7010 g_assert (i
< iter
->sig
->param_count
);
7012 return iter
->sig
->params
[i
];
7016 mono_TypedReference_ToObject (MonoTypedRef tref
)
7018 MONO_ARCH_SAVE_REGS
;
7020 if (MONO_TYPE_IS_REFERENCE (tref
.type
)) {
7021 MonoObject
** objp
= tref
.value
;
7025 return mono_value_box (mono_domain_get (), tref
.klass
, tref
.value
);
7029 mono_TypedReference_ToObjectInternal (MonoType
*type
, gpointer value
, MonoClass
*klass
)
7031 MONO_ARCH_SAVE_REGS
;
7033 if (MONO_TYPE_IS_REFERENCE (type
)) {
7034 MonoObject
** objp
= value
;
7038 return mono_value_box (mono_domain_get (), klass
, value
);
7042 prelink_method (MonoMethod
*method
)
7044 const char *exc_class
, *exc_arg
;
7045 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7047 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7049 mono_raise_exception(
7050 mono_exception_from_name_msg (mono_defaults
.corlib
, "System", exc_class
, exc_arg
) );
7052 /* create the wrapper, too? */
7056 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod
*method
)
7058 MONO_ARCH_SAVE_REGS
;
7059 prelink_method (method
->method
);
7063 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
*type
)
7065 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
7067 gpointer iter
= NULL
;
7068 MONO_ARCH_SAVE_REGS
;
7070 while ((m
= mono_class_get_methods (klass
, &iter
)))
7074 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7076 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7077 gint32
const **exponents
,
7078 gunichar2
const **digitLowerTable
,
7079 gunichar2
const **digitUpperTable
,
7080 gint64
const **tenPowersList
,
7081 gint32
const **decHexDigits
)
7083 *mantissas
= Formatter_MantissaBitsTable
;
7084 *exponents
= Formatter_TensExponentTable
;
7085 *digitLowerTable
= Formatter_DigitLowerTable
;
7086 *digitUpperTable
= Formatter_DigitUpperTable
;
7087 *tenPowersList
= Formatter_TenPowersList
;
7088 *decHexDigits
= Formatter_DecHexDigits
;
7091 /* These parameters are "readonly" in corlib/System/Char.cs */
7093 ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data
,
7094 guint8
const **numeric_data
,
7095 gdouble
const **numeric_data_values
,
7096 guint16
const **to_lower_data_low
,
7097 guint16
const **to_lower_data_high
,
7098 guint16
const **to_upper_data_low
,
7099 guint16
const **to_upper_data_high
)
7101 *category_data
= CategoryData
;
7102 *numeric_data
= NumericData
;
7103 *numeric_data_values
= NumericDataValues
;
7104 *to_lower_data_low
= ToLowerDataLow
;
7105 *to_lower_data_high
= ToLowerDataHigh
;
7106 *to_upper_data_low
= ToUpperDataLow
;
7107 *to_upper_data_high
= ToUpperDataHigh
;
7111 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod
*method
)
7113 return method
->method
->token
;
7117 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7118 * and avoid useless allocations.
7121 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
)
7125 for (i
= 0; i
< type
->num_mods
; ++i
) {
7126 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7131 res
= mono_array_new (mono_domain_get (), mono_defaults
.systemtype_class
, count
);
7133 for (i
= 0; i
< type
->num_mods
; ++i
) {
7134 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7135 MonoClass
*klass
= mono_class_get (image
, type
->modifiers
[i
].token
);
7136 mono_array_setref (res
, count
, mono_type_get_object (mono_domain_get (), &klass
->byval_arg
));
7144 param_info_get_type_modifiers (MonoReflectionParameter
*param
, MonoBoolean optional
)
7146 MonoType
*type
= param
->ClassImpl
->type
;
7147 MonoClass
*member_class
= mono_object_class (param
->MemberImpl
);
7148 MonoMethod
*method
= NULL
;
7151 MonoMethodSignature
*sig
;
7153 if (mono_class_is_reflection_method_or_constructor (member_class
)) {
7154 MonoReflectionMethod
*rmethod
= (MonoReflectionMethod
*)param
->MemberImpl
;
7155 method
= rmethod
->method
;
7156 } else if (member_class
->image
== mono_defaults
.corlib
&& !strcmp ("MonoProperty", member_class
->name
)) {
7157 MonoReflectionProperty
*prop
= (MonoReflectionProperty
*)param
->MemberImpl
;
7158 if (!(method
= prop
->property
->get
))
7159 method
= prop
->property
->set
;
7162 char *type_name
= mono_type_get_full_name (member_class
);
7163 char *msg
= g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name
);
7164 MonoException
*ex
= mono_get_exception_not_supported (msg
);
7167 mono_raise_exception (ex
);
7170 image
= method
->klass
->image
;
7171 pos
= param
->PositionImpl
;
7172 sig
= mono_method_signature (method
);
7176 type
= sig
->params
[pos
];
7178 return type_array_from_modifiers (image
, type
, optional
);
7182 get_property_type (MonoProperty
*prop
)
7184 MonoMethodSignature
*sig
;
7186 sig
= mono_method_signature (prop
->get
);
7188 } else if (prop
->set
) {
7189 sig
= mono_method_signature (prop
->set
);
7190 return sig
->params
[sig
->param_count
- 1];
7196 property_info_get_type_modifiers (MonoReflectionProperty
*property
, MonoBoolean optional
)
7198 MonoType
*type
= get_property_type (property
->property
);
7199 MonoImage
*image
= property
->klass
->image
;
7203 return type_array_from_modifiers (image
, type
, optional
);
7207 *Construct a MonoType suited to be used to decode a constant blob object.
7209 * @type is the target type which will be constructed
7210 * @blob_type is the blob type, for example, that comes from the constant table
7211 * @real_type is the expected constructed type.
7214 mono_type_from_blob_type (MonoType
*type
, MonoTypeEnum blob_type
, MonoType
*real_type
)
7216 type
->type
= blob_type
;
7217 type
->data
.klass
= NULL
;
7218 if (blob_type
== MONO_TYPE_CLASS
)
7219 type
->data
.klass
= mono_defaults
.object_class
;
7220 else if (real_type
->type
== MONO_TYPE_VALUETYPE
&& real_type
->data
.klass
->enumtype
) {
7221 /* For enums, we need to use the base type */
7222 type
->type
= MONO_TYPE_VALUETYPE
;
7223 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7225 type
->data
.klass
= mono_class_from_mono_type (real_type
);
7229 property_info_get_default_value (MonoReflectionProperty
*property
)
7232 MonoProperty
*prop
= property
->property
;
7233 MonoType
*type
= get_property_type (prop
);
7234 MonoDomain
*domain
= mono_object_domain (property
);
7235 MonoTypeEnum def_type
;
7236 const char *def_value
;
7239 g_assert (!prop
->parent
->image
->dynamic
);
7241 mono_class_init (prop
->parent
);
7243 if (!(prop
->attrs
& PROPERTY_ATTRIBUTE_HAS_DEFAULT
))
7244 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
7246 def_value
= mono_class_get_property_default_value (prop
, &def_type
);
7248 mono_type_from_blob_type (&blob_type
, def_type
, type
);
7249 o
= mono_get_object_from_blob (domain
, &blob_type
, def_value
);
7255 custom_attrs_defined_internal (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7257 MonoCustomAttrInfo
*cinfo
;
7260 cinfo
= mono_reflection_get_custom_attrs_info (obj
);
7263 found
= mono_custom_attrs_has_attr (cinfo
, mono_class_from_mono_type (attr_type
->type
));
7265 mono_custom_attrs_free (cinfo
);
7270 custom_attrs_get_by_type (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7272 MonoArray
*res
= mono_reflection_get_custom_attrs_by_type (obj
, attr_type
? mono_class_from_mono_type (attr_type
->type
) : NULL
);
7274 if (mono_loader_get_last_error ()) {
7275 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7276 g_assert_not_reached ();
7285 ves_icall_Mono_Runtime_GetDisplayName (void)
7288 MonoString
*display_name
;
7290 info
= mono_get_runtime_callbacks ()->get_runtime_build_info ();
7291 display_name
= mono_string_new (mono_domain_get (), info
);
7293 return display_name
;
7297 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code
)
7299 MonoString
*message
;
7303 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
7304 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, code
, 0,
7307 message
= mono_string_new (mono_domain_get (), "Error looking up error string");
7309 message
= mono_string_new_utf16 (mono_domain_get (), buf
, ret
);
7317 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7318 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7319 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7320 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7321 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7322 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7323 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7324 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7328 base64_to_byte_array (gunichar2
*start
, gint ilength
, MonoBoolean allowWhitespaceOnly
)
7333 gunichar2 last
, prev_last
, prev2_last
;
7341 last
= prev_last
= 0, prev2_last
= 0;
7342 for (i
= 0; i
< ilength
; i
++) {
7344 if (c
>= sizeof (dbase64
)) {
7345 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7346 "System", "FormatException",
7347 "Invalid character found.");
7348 mono_raise_exception (exc
);
7349 } else if (isspace (c
)) {
7352 prev2_last
= prev_last
;
7358 olength
= ilength
- ignored
;
7360 if (allowWhitespaceOnly
&& olength
== 0) {
7361 return mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, 0);
7364 if ((olength
& 3) != 0 || olength
<= 0) {
7365 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System",
7366 "FormatException", "Invalid length.");
7367 mono_raise_exception (exc
);
7370 if (prev2_last
== '=') {
7371 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7372 mono_raise_exception (exc
);
7375 olength
= (olength
* 3) / 4;
7379 if (prev_last
== '=')
7382 result
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, olength
);
7383 res_ptr
= mono_array_addr (result
, guchar
, 0);
7384 for (i
= 0; i
< ilength
; ) {
7387 for (k
= 0; k
< 4 && i
< ilength
;) {
7393 if (((b
[k
] = dbase64
[c
]) & 0x80) != 0) {
7394 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7395 "System", "FormatException",
7396 "Invalid character found.");
7397 mono_raise_exception (exc
);
7402 *res_ptr
++ = (b
[0] << 2) | (b
[1] >> 4);
7404 *res_ptr
++ = (b
[1] << 4) | (b
[2] >> 2);
7406 *res_ptr
++ = (b
[2] << 6) | b
[3];
7408 while (i
< ilength
&& isspace (start
[i
]))
7416 InternalFromBase64String (MonoString
*str
, MonoBoolean allowWhitespaceOnly
)
7418 MONO_ARCH_SAVE_REGS
;
7420 return base64_to_byte_array (mono_string_chars (str
),
7421 mono_string_length (str
), allowWhitespaceOnly
);
7425 InternalFromBase64CharArray (MonoArray
*input
, gint offset
, gint length
)
7427 MONO_ARCH_SAVE_REGS
;
7429 return base64_to_byte_array (mono_array_addr (input
, gunichar2
, offset
),
7433 #define ICALL_TYPE(id,name,first)
7434 #define ICALL(id,name,func) Icall_ ## id,
7437 #include "metadata/icall-def.h"
7443 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7444 #define ICALL(id,name,func)
7446 #include "metadata/icall-def.h"
7452 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7453 #define ICALL(id,name,func)
7455 guint16 first_icall
;
7458 static const IcallTypeDesc
7459 icall_type_descs
[] = {
7460 #include "metadata/icall-def.h"
7464 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7467 #define ICALL_TYPE(id,name,first)
7470 #ifdef HAVE_ARRAY_ELEM_INIT
7471 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7472 #define MSGSTRFIELD1(line) str##line
7474 static const struct msgstrtn_t
{
7475 #define ICALL(id,name,func)
7477 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7478 #include "metadata/icall-def.h"
7480 } icall_type_names_str
= {
7481 #define ICALL_TYPE(id,name,first) (name),
7482 #include "metadata/icall-def.h"
7485 static const guint16 icall_type_names_idx
[] = {
7486 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7487 #include "metadata/icall-def.h"
7490 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7492 static const struct msgstr_t
{
7494 #define ICALL_TYPE(id,name,first)
7495 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7496 #include "metadata/icall-def.h"
7498 } icall_names_str
= {
7499 #define ICALL(id,name,func) (name),
7500 #include "metadata/icall-def.h"
7503 static const guint16 icall_names_idx
[] = {
7504 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7505 #include "metadata/icall-def.h"
7508 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7514 #define ICALL_TYPE(id,name,first) name,
7515 #define ICALL(id,name,func)
7516 static const char* const
7517 icall_type_names
[] = {
7518 #include "metadata/icall-def.h"
7522 #define icall_type_name_get(id) (icall_type_names [(id)])
7526 #define ICALL_TYPE(id,name,first)
7527 #define ICALL(id,name,func) name,
7528 static const char* const
7530 #include "metadata/icall-def.h"
7533 #define icall_name_get(id) icall_names [(id)]
7535 #endif /* !HAVE_ARRAY_ELEM_INIT */
7539 #define ICALL_TYPE(id,name,first)
7540 #define ICALL(id,name,func) func,
7541 static const gconstpointer
7542 icall_functions
[] = {
7543 #include "metadata/icall-def.h"
7547 static GHashTable
*icall_hash
= NULL
;
7548 static GHashTable
*jit_icall_hash_name
= NULL
;
7549 static GHashTable
*jit_icall_hash_addr
= NULL
;
7552 mono_icall_init (void)
7556 /* check that tables are sorted: disable in release */
7559 const char *prev_class
= NULL
;
7560 const char *prev_method
;
7562 for (i
= 0; i
< Icall_type_num
; ++i
) {
7563 const IcallTypeDesc
*desc
;
7566 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
7567 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
7568 prev_class
= icall_type_name_get (i
);
7569 desc
= &icall_type_descs
[i
];
7570 num_icalls
= icall_desc_num_icalls (desc
);
7571 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7572 for (j
= 0; j
< num_icalls
; ++j
) {
7573 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
7574 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
7575 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
7576 prev_method
= methodn
;
7581 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
7585 mono_icall_cleanup (void)
7587 g_hash_table_destroy (icall_hash
);
7588 g_hash_table_destroy (jit_icall_hash_name
);
7589 g_hash_table_destroy (jit_icall_hash_addr
);
7593 mono_add_internal_call (const char *name
, gconstpointer method
)
7595 mono_loader_lock ();
7597 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
7599 mono_loader_unlock ();
7602 #ifdef HAVE_ARRAY_ELEM_INIT
7604 compare_method_imap (const void *key
, const void *elem
)
7606 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
7607 return strcmp (key
, method_name
);
7611 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7613 const guint16
*nameslot
= bsearch (name
, icall_names_idx
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names_idx
[0]), compare_method_imap
);
7616 return (gpointer
)icall_functions
[(nameslot
- &icall_names_idx
[0])];
7620 compare_class_imap (const void *key
, const void *elem
)
7622 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
7623 return strcmp (key
, class_name
);
7626 static const IcallTypeDesc
*
7627 find_class_icalls (const char *name
)
7629 const guint16
*nameslot
= bsearch (name
, icall_type_names_idx
, Icall_type_num
, sizeof (icall_type_names_idx
[0]), compare_class_imap
);
7632 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
7637 compare_method_imap (const void *key
, const void *elem
)
7639 const char** method_name
= (const char**)elem
;
7640 return strcmp (key
, *method_name
);
7644 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7646 const char **nameslot
= bsearch (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
7649 return (gpointer
)icall_functions
[(nameslot
- icall_names
)];
7653 compare_class_imap (const void *key
, const void *elem
)
7655 const char** class_name
= (const char**)elem
;
7656 return strcmp (key
, *class_name
);
7659 static const IcallTypeDesc
*
7660 find_class_icalls (const char *name
)
7662 const char **nameslot
= bsearch (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
7665 return &icall_type_descs
[nameslot
- icall_type_names
];
7671 * we should probably export this as an helper (handle nested types).
7672 * Returns the number of chars written in buf.
7675 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
7677 int nspacelen
, cnamelen
;
7678 nspacelen
= strlen (klass
->name_space
);
7679 cnamelen
= strlen (klass
->name
);
7680 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
7683 memcpy (buf
, klass
->name_space
, nspacelen
);
7684 buf
[nspacelen
++] = '.';
7686 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
7687 buf
[nspacelen
+ cnamelen
] = 0;
7688 return nspacelen
+ cnamelen
;
7692 mono_lookup_internal_call (MonoMethod
*method
)
7697 int typelen
= 0, mlen
, siglen
;
7699 const IcallTypeDesc
*imap
;
7701 g_assert (method
!= NULL
);
7703 if (method
->is_inflated
)
7704 method
= ((MonoMethodInflated
*) method
)->declaring
;
7706 if (method
->klass
->nested_in
) {
7707 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
7711 mname
[pos
++] = '/';
7714 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
7720 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
7725 imap
= find_class_icalls (mname
);
7727 mname
[typelen
] = ':';
7728 mname
[typelen
+ 1] = ':';
7730 mlen
= strlen (method
->name
);
7731 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
7732 sigstart
= mname
+ typelen
+ 2 + mlen
;
7735 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
7736 siglen
= strlen (tmpsig
);
7737 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
7740 memcpy (sigstart
+ 1, tmpsig
, siglen
);
7741 sigstart
[siglen
+ 1] = ')';
7742 sigstart
[siglen
+ 2] = 0;
7745 mono_loader_lock ();
7747 res
= g_hash_table_lookup (icall_hash
, mname
);
7749 mono_loader_unlock ();
7752 /* try without signature */
7754 res
= g_hash_table_lookup (icall_hash
, mname
);
7756 mono_loader_unlock ();
7760 /* it wasn't found in the static call tables */
7762 mono_loader_unlock ();
7765 res
= find_method_icall (imap
, sigstart
- mlen
);
7767 mono_loader_unlock ();
7770 /* try _with_ signature */
7772 res
= find_method_icall (imap
, sigstart
- mlen
);
7774 mono_loader_unlock ();
7778 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
7779 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7780 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
7781 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7782 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");
7783 g_print ("If you see other errors or faults after this message they are probably related\n");
7784 g_print ("and you need to fix your mono install first.\n");
7786 mono_loader_unlock ();
7792 type_from_typename (char *typename
)
7794 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
7796 if (!strcmp (typename
, "int"))
7797 klass
= mono_defaults
.int_class
;
7798 else if (!strcmp (typename
, "ptr"))
7799 klass
= mono_defaults
.int_class
;
7800 else if (!strcmp (typename
, "void"))
7801 klass
= mono_defaults
.void_class
;
7802 else if (!strcmp (typename
, "int32"))
7803 klass
= mono_defaults
.int32_class
;
7804 else if (!strcmp (typename
, "uint32"))
7805 klass
= mono_defaults
.uint32_class
;
7806 else if (!strcmp (typename
, "int8"))
7807 klass
= mono_defaults
.sbyte_class
;
7808 else if (!strcmp (typename
, "uint8"))
7809 klass
= mono_defaults
.byte_class
;
7810 else if (!strcmp (typename
, "int16"))
7811 klass
= mono_defaults
.int16_class
;
7812 else if (!strcmp (typename
, "uint16"))
7813 klass
= mono_defaults
.uint16_class
;
7814 else if (!strcmp (typename
, "long"))
7815 klass
= mono_defaults
.int64_class
;
7816 else if (!strcmp (typename
, "ulong"))
7817 klass
= mono_defaults
.uint64_class
;
7818 else if (!strcmp (typename
, "float"))
7819 klass
= mono_defaults
.single_class
;
7820 else if (!strcmp (typename
, "double"))
7821 klass
= mono_defaults
.double_class
;
7822 else if (!strcmp (typename
, "object"))
7823 klass
= mono_defaults
.object_class
;
7824 else if (!strcmp (typename
, "obj"))
7825 klass
= mono_defaults
.object_class
;
7826 else if (!strcmp (typename
, "string"))
7827 klass
= mono_defaults
.string_class
;
7828 else if (!strcmp (typename
, "bool"))
7829 klass
= mono_defaults
.boolean_class
;
7830 else if (!strcmp (typename
, "boolean"))
7831 klass
= mono_defaults
.boolean_class
;
7833 g_error ("%s", typename
);
7834 g_assert_not_reached ();
7836 return &klass
->byval_arg
;
7839 MonoMethodSignature
*
7840 mono_create_icall_signature (const char *sigstr
)
7845 MonoMethodSignature
*res
;
7847 mono_loader_lock ();
7848 res
= g_hash_table_lookup (mono_defaults
.corlib
->helper_signatures
, sigstr
);
7850 mono_loader_unlock ();
7854 parts
= g_strsplit (sigstr
, " ", 256);
7863 res
= mono_metadata_signature_alloc (mono_defaults
.corlib
, len
- 1);
7868 * Under windows, the default pinvoke calling convention is STDCALL but
7871 res
->call_convention
= MONO_CALL_C
;
7874 res
->ret
= type_from_typename (parts
[0]);
7875 for (i
= 1; i
< len
; ++i
) {
7876 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
7881 g_hash_table_insert (mono_defaults
.corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
7883 mono_loader_unlock ();
7889 mono_find_jit_icall_by_name (const char *name
)
7891 MonoJitICallInfo
*info
;
7892 g_assert (jit_icall_hash_name
);
7894 mono_loader_lock ();
7895 info
= g_hash_table_lookup (jit_icall_hash_name
, name
);
7896 mono_loader_unlock ();
7901 mono_find_jit_icall_by_addr (gconstpointer addr
)
7903 MonoJitICallInfo
*info
;
7904 g_assert (jit_icall_hash_addr
);
7906 mono_loader_lock ();
7907 info
= g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
7908 mono_loader_unlock ();
7914 * mono_get_jit_icall_info:
7916 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7917 * caller should access it while holding the loader lock.
7920 mono_get_jit_icall_info (void)
7922 return jit_icall_hash_name
;
7926 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
7928 mono_loader_lock ();
7929 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
7930 mono_loader_unlock ();
7934 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
7936 MonoJitICallInfo
*info
;
7941 mono_loader_lock ();
7943 if (!jit_icall_hash_name
) {
7944 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
7945 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
7948 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
7949 g_warning ("jit icall already defined \"%s\"\n", name
);
7950 g_assert_not_reached ();
7953 info
= g_new0 (MonoJitICallInfo
, 1);
7960 info
->wrapper
= func
;
7962 info
->wrapper
= NULL
;
7965 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
7966 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
7968 mono_loader_unlock ();