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>
78 #if defined (HOST_WIN32)
84 static MonoReflectionAssembly
* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
87 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
);
89 /* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
90 * It works by allocating an initial small array on stack and only going to malloc'd memory if needed.
98 #define MONO_PTR_ARRAY_MAX_ON_STACK (16)
100 #define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
102 (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
103 (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); \
106 #define mono_ptr_array_destroy(ARRAY) do {\
107 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
108 mono_gc_free_fixed ((ARRAY).data); \
111 #define mono_ptr_array_append(ARRAY, VALUE) do { \
112 if ((ARRAY).size >= (ARRAY).capacity) {\
113 void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
114 memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
115 if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
116 mono_gc_free_fixed ((ARRAY).data); \
117 (ARRAY).data = __tmp; \
118 (ARRAY).capacity *= 2;\
120 ((ARRAY).data [(ARRAY).size++] = VALUE); \
123 #define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
124 ((ARRAY).data [(IDX)] = VALUE); \
127 #define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
129 #define mono_ptr_array_size(ARRAY) ((ARRAY).size)
132 static inline MonoBoolean
133 is_generic_parameter (MonoType
*type
)
135 return !type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
);
139 * We expect a pointer to a char, not a string
142 mono_double_ParseImpl (char *ptr
, double *result
)
144 gchar
*endptr
= NULL
;
151 *result
= strtod (ptr
, &endptr
);
155 /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
156 EnterCriticalSection (&mono_strtod_mutex
);
157 *result
= mono_strtod (ptr
, &endptr
);
158 LeaveCriticalSection (&mono_strtod_mutex
);
160 *result
= mono_strtod (ptr
, &endptr
);
165 if (!*ptr
|| (endptr
&& *endptr
))
172 ves_icall_System_Array_GetValueImpl (MonoObject
*this, guint32 pos
)
181 ao
= (MonoArray
*)this;
182 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
184 esize
= mono_array_element_size (ac
);
185 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
187 if (ac
->element_class
->valuetype
)
188 return mono_value_box (this->vtable
->domain
, ac
->element_class
, ea
);
194 ves_icall_System_Array_GetValue (MonoObject
*this, MonoObject
*idxs
)
202 MONO_CHECK_ARG_NULL (idxs
);
204 io
= (MonoArray
*)idxs
;
205 ic
= (MonoClass
*)io
->obj
.vtable
->klass
;
207 ao
= (MonoArray
*)this;
208 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
210 g_assert (ic
->rank
== 1);
211 if (io
->bounds
!= NULL
|| io
->max_length
!= ac
->rank
)
212 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
214 ind
= (gint32
*)io
->vector
;
216 if (ao
->bounds
== NULL
) {
217 if (*ind
< 0 || *ind
>= ao
->max_length
)
218 mono_raise_exception (mono_get_exception_index_out_of_range ());
220 return ves_icall_System_Array_GetValueImpl (this, *ind
);
223 for (i
= 0; i
< ac
->rank
; i
++)
224 if ((ind
[i
] < ao
->bounds
[i
].lower_bound
) ||
225 (ind
[i
] >= (mono_array_lower_bound_t
)ao
->bounds
[i
].length
+ ao
->bounds
[i
].lower_bound
))
226 mono_raise_exception (mono_get_exception_index_out_of_range ());
228 pos
= ind
[0] - ao
->bounds
[0].lower_bound
;
229 for (i
= 1; i
< ac
->rank
; i
++)
230 pos
= pos
*ao
->bounds
[i
].length
+ ind
[i
] -
231 ao
->bounds
[i
].lower_bound
;
233 return ves_icall_System_Array_GetValueImpl (this, pos
);
237 ves_icall_System_Array_SetValueImpl (MonoArray
*this, MonoObject
*value
, guint32 pos
)
239 MonoClass
*ac
, *vc
, *ec
;
251 vc
= value
->vtable
->klass
;
255 ac
= this->obj
.vtable
->klass
;
256 ec
= ac
->element_class
;
258 esize
= mono_array_element_size (ac
);
259 ea
= (gpointer
*)((char*)this->vector
+ (pos
* esize
));
260 va
= (gpointer
*)((char*)value
+ sizeof (MonoObject
));
263 memset (ea
, 0, esize
);
267 #define NO_WIDENING_CONVERSION G_STMT_START{\
268 mono_raise_exception (mono_get_exception_argument ( \
269 "value", "not a widening conversion")); \
272 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
273 if (esize < vsize + (extra)) \
274 mono_raise_exception (mono_get_exception_argument ( \
275 "value", "not a widening conversion")); \
278 #define INVALID_CAST G_STMT_START{\
279 mono_raise_exception (mono_get_exception_invalid_cast ()); \
282 /* Check element (destination) type. */
283 switch (ec
->byval_arg
.type
) {
284 case MONO_TYPE_STRING
:
285 switch (vc
->byval_arg
.type
) {
286 case MONO_TYPE_STRING
:
292 case MONO_TYPE_BOOLEAN
:
293 switch (vc
->byval_arg
.type
) {
294 case MONO_TYPE_BOOLEAN
:
307 NO_WIDENING_CONVERSION
;
314 if (!ec
->valuetype
) {
315 if (!mono_object_isinst (value
, ec
))
317 mono_gc_wbarrier_set_arrayref (this, ea
, (MonoObject
*)value
);
321 if (mono_object_isinst (value
, ec
)) {
322 if (ec
->has_references
)
323 mono_value_copy (ea
, (char*)value
+ sizeof (MonoObject
), ec
);
325 memcpy (ea
, (char *)value
+ sizeof (MonoObject
), esize
);
332 vsize
= mono_class_instance_size (vc
) - sizeof (MonoObject
);
334 et
= ec
->byval_arg
.type
;
335 if (et
== MONO_TYPE_VALUETYPE
&& ec
->byval_arg
.data
.klass
->enumtype
)
336 et
= mono_class_enum_basetype (ec
->byval_arg
.data
.klass
)->type
;
338 vt
= vc
->byval_arg
.type
;
339 if (vt
== MONO_TYPE_VALUETYPE
&& vc
->byval_arg
.data
.klass
->enumtype
)
340 vt
= mono_class_enum_basetype (vc
->byval_arg
.data
.klass
)->type
;
342 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
348 case MONO_TYPE_CHAR: \
349 CHECK_WIDENING_CONVERSION(0); \
350 *(etype *) ea = (etype) u64; \
352 /* You can't assign a signed value to an unsigned array. */ \
357 /* You can't assign a floating point number to an integer array. */ \
360 NO_WIDENING_CONVERSION; \
364 #define ASSIGN_SIGNED(etype) G_STMT_START{\
370 CHECK_WIDENING_CONVERSION(0); \
371 *(etype *) ea = (etype) i64; \
373 /* You can assign an unsigned value to a signed array if the array's */ \
374 /* element size is larger than the value size. */ \
379 case MONO_TYPE_CHAR: \
380 CHECK_WIDENING_CONVERSION(1); \
381 *(etype *) ea = (etype) u64; \
383 /* You can't assign a floating point number to an integer array. */ \
386 NO_WIDENING_CONVERSION; \
390 #define ASSIGN_REAL(etype) G_STMT_START{\
394 CHECK_WIDENING_CONVERSION(0); \
395 *(etype *) ea = (etype) r64; \
397 /* All integer values fit into a floating point array, so we don't */ \
398 /* need to CHECK_WIDENING_CONVERSION here. */ \
403 *(etype *) ea = (etype) i64; \
409 case MONO_TYPE_CHAR: \
410 *(etype *) ea = (etype) u64; \
417 u64
= *(guint8
*) va
;
420 u64
= *(guint16
*) va
;
423 u64
= *(guint32
*) va
;
426 u64
= *(guint64
*) va
;
432 i64
= *(gint16
*) va
;
435 i64
= *(gint32
*) va
;
438 i64
= *(gint64
*) va
;
441 r64
= *(gfloat
*) va
;
444 r64
= *(gdouble
*) va
;
447 u64
= *(guint16
*) va
;
449 case MONO_TYPE_BOOLEAN
:
450 /* Boolean is only compatible with itself. */
463 NO_WIDENING_CONVERSION
;
470 /* If we can't do a direct copy, let's try a widening conversion. */
473 ASSIGN_UNSIGNED (guint16
);
475 ASSIGN_UNSIGNED (guint8
);
477 ASSIGN_UNSIGNED (guint16
);
479 ASSIGN_UNSIGNED (guint32
);
481 ASSIGN_UNSIGNED (guint64
);
483 ASSIGN_SIGNED (gint8
);
485 ASSIGN_SIGNED (gint16
);
487 ASSIGN_SIGNED (gint32
);
489 ASSIGN_SIGNED (gint64
);
491 ASSIGN_REAL (gfloat
);
493 ASSIGN_REAL (gdouble
);
497 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
501 #undef NO_WIDENING_CONVERSION
502 #undef CHECK_WIDENING_CONVERSION
503 #undef ASSIGN_UNSIGNED
509 ves_icall_System_Array_SetValue (MonoArray
*this, MonoObject
*value
,
517 MONO_CHECK_ARG_NULL (idxs
);
519 ic
= idxs
->obj
.vtable
->klass
;
520 ac
= this->obj
.vtable
->klass
;
522 g_assert (ic
->rank
== 1);
523 if (idxs
->bounds
!= NULL
|| idxs
->max_length
!= ac
->rank
)
524 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
526 ind
= (gint32
*)idxs
->vector
;
528 if (this->bounds
== NULL
) {
529 if (*ind
< 0 || *ind
>= this->max_length
)
530 mono_raise_exception (mono_get_exception_index_out_of_range ());
532 ves_icall_System_Array_SetValueImpl (this, value
, *ind
);
536 for (i
= 0; i
< ac
->rank
; i
++)
537 if ((ind
[i
] < this->bounds
[i
].lower_bound
) ||
538 (ind
[i
] >= (mono_array_lower_bound_t
)this->bounds
[i
].length
+ this->bounds
[i
].lower_bound
))
539 mono_raise_exception (mono_get_exception_index_out_of_range ());
541 pos
= ind
[0] - this->bounds
[0].lower_bound
;
542 for (i
= 1; i
< ac
->rank
; i
++)
543 pos
= pos
* this->bounds
[i
].length
+ ind
[i
] -
544 this->bounds
[i
].lower_bound
;
546 ves_icall_System_Array_SetValueImpl (this, value
, pos
);
550 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
554 mono_array_size_t
*sizes
, i
;
555 gboolean bounded
= FALSE
;
559 MONO_CHECK_ARG_NULL (type
);
560 MONO_CHECK_ARG_NULL (lengths
);
562 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
564 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
566 for (i
= 0; i
< mono_array_length (lengths
); i
++)
567 if (mono_array_get (lengths
, gint32
, i
) < 0)
568 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
570 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint32
, 0) != 0))
571 /* vectors are not the same as one dimensional arrays with no-zero bounds */
576 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
578 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
579 for (i
= 0; i
< aklass
->rank
; ++i
) {
580 sizes
[i
] = mono_array_get (lengths
, guint32
, i
);
582 sizes
[i
+ aklass
->rank
] = mono_array_get (bounds
, guint32
, i
);
584 sizes
[i
+ aklass
->rank
] = 0;
587 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
593 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
597 mono_array_size_t
*sizes
, i
;
598 gboolean bounded
= FALSE
;
602 MONO_CHECK_ARG_NULL (type
);
603 MONO_CHECK_ARG_NULL (lengths
);
605 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
607 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
609 for (i
= 0; i
< mono_array_length (lengths
); i
++)
610 if ((mono_array_get (lengths
, gint64
, i
) < 0) ||
611 (mono_array_get (lengths
, gint64
, i
) > MONO_ARRAY_MAX_INDEX
))
612 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
614 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint64
, 0) != 0))
615 /* vectors are not the same as one dimensional arrays with no-zero bounds */
620 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
622 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
623 for (i
= 0; i
< aklass
->rank
; ++i
) {
624 sizes
[i
] = mono_array_get (lengths
, guint64
, i
);
626 sizes
[i
+ aklass
->rank
] = (mono_array_size_t
) mono_array_get (bounds
, guint64
, i
);
628 sizes
[i
+ aklass
->rank
] = 0;
631 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
637 ves_icall_System_Array_GetRank (MonoObject
*this)
641 return this->vtable
->klass
->rank
;
645 ves_icall_System_Array_GetLength (MonoArray
*this, gint32 dimension
)
647 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
648 mono_array_size_t length
;
652 if ((dimension
< 0) || (dimension
>= rank
))
653 mono_raise_exception (mono_get_exception_index_out_of_range ());
655 if (this->bounds
== NULL
)
656 length
= this->max_length
;
658 length
= this->bounds
[dimension
].length
;
660 #ifdef MONO_BIG_ARRAYS
661 if (length
> G_MAXINT32
)
662 mono_raise_exception (mono_get_exception_overflow ());
668 ves_icall_System_Array_GetLongLength (MonoArray
*this, gint32 dimension
)
670 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
674 if ((dimension
< 0) || (dimension
>= rank
))
675 mono_raise_exception (mono_get_exception_index_out_of_range ());
677 if (this->bounds
== NULL
)
678 return this->max_length
;
680 return this->bounds
[dimension
].length
;
684 ves_icall_System_Array_GetLowerBound (MonoArray
*this, gint32 dimension
)
686 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
690 if ((dimension
< 0) || (dimension
>= rank
))
691 mono_raise_exception (mono_get_exception_index_out_of_range ());
693 if (this->bounds
== NULL
)
696 return this->bounds
[dimension
].lower_bound
;
700 ves_icall_System_Array_ClearInternal (MonoArray
*arr
, int idx
, int length
)
702 int sz
= mono_array_element_size (mono_object_class (arr
));
703 memset (mono_array_addr_with_size (arr
, sz
, idx
), 0, length
* sz
);
707 ves_icall_System_Array_FastCopy (MonoArray
*source
, int source_idx
, MonoArray
* dest
, int dest_idx
, int length
)
712 MonoClass
*src_class
;
713 MonoClass
*dest_class
;
718 if (source
->obj
.vtable
->klass
->rank
!= dest
->obj
.vtable
->klass
->rank
)
721 if (source
->bounds
|| dest
->bounds
)
724 /* there's no integer overflow since mono_array_length returns an unsigned integer */
725 if ((dest_idx
+ length
> mono_array_length (dest
)) ||
726 (source_idx
+ length
> mono_array_length (source
)))
729 src_class
= source
->obj
.vtable
->klass
->element_class
;
730 dest_class
= dest
->obj
.vtable
->klass
->element_class
;
733 * Handle common cases.
736 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
737 if (src_class
== mono_defaults
.object_class
&& dest_class
->valuetype
) {
738 int has_refs
= dest_class
->has_references
;
739 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
740 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
741 if (elem
&& !mono_object_isinst (elem
, dest_class
))
745 element_size
= mono_array_element_size (dest
->obj
.vtable
->klass
);
746 memset (mono_array_addr_with_size (dest
, element_size
, dest_idx
), 0, element_size
* length
);
747 for (i
= 0; i
< length
; ++i
) {
748 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, source_idx
+ i
);
749 void *addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
+ i
);
753 mono_value_copy (addr
, (char *)elem
+ sizeof (MonoObject
), dest_class
);
755 memcpy (addr
, (char *)elem
+ sizeof (MonoObject
), element_size
);
760 /* Check if we're copying a char[] <==> (u)short[] */
761 if (src_class
!= dest_class
) {
762 if (dest_class
->valuetype
|| dest_class
->enumtype
|| src_class
->valuetype
|| src_class
->enumtype
)
765 if (mono_class_is_subclass_of (src_class
, dest_class
, FALSE
))
767 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
768 else if (mono_class_is_subclass_of (dest_class
, src_class
, FALSE
))
769 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
770 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
771 if (elem
&& !mono_object_isinst (elem
, dest_class
))
778 if (dest_class
->valuetype
) {
779 element_size
= mono_array_element_size (source
->obj
.vtable
->klass
);
780 source_addr
= mono_array_addr_with_size (source
, element_size
, source_idx
);
781 if (dest_class
->has_references
) {
782 mono_value_copy_array (dest
, dest_idx
, source_addr
, length
);
784 dest_addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
);
785 memmove (dest_addr
, source_addr
, element_size
* length
);
788 mono_array_memcpy_refs (dest
, dest_idx
, source
, source_idx
, length
);
795 ves_icall_System_Array_GetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
804 ao
= (MonoArray
*)this;
805 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
807 esize
= mono_array_element_size (ac
);
808 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
810 memcpy (value
, ea
, esize
);
814 ves_icall_System_Array_SetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
823 ao
= (MonoArray
*)this;
824 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
825 ec
= ac
->element_class
;
827 esize
= mono_array_element_size (ac
);
828 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
830 if (MONO_TYPE_IS_REFERENCE (&ec
->byval_arg
)) {
831 g_assert (esize
== sizeof (gpointer
));
832 mono_gc_wbarrier_generic_store (ea
, *(gpointer
*)value
);
834 g_assert (ec
->inited
);
835 g_assert (esize
== mono_class_value_size (ec
, NULL
));
836 if (ec
->has_references
)
837 mono_gc_wbarrier_value_copy (ea
, value
, 1, ec
);
839 memcpy (ea
, value
, esize
);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray
*array
, MonoClassField
*field_handle
)
846 MonoClass
*klass
= array
->obj
.vtable
->klass
;
847 guint32 size
= mono_array_element_size (klass
);
848 MonoType
*type
= mono_type_get_underlying_type (&klass
->element_class
->byval_arg
);
850 const char *field_data
;
852 if (MONO_TYPE_IS_REFERENCE (type
) ||
853 (type
->type
== MONO_TYPE_VALUETYPE
&&
854 (!mono_type_get_class (type
) ||
855 mono_type_get_class (type
)->has_references
))) {
856 MonoException
*exc
= mono_get_exception_argument("array",
857 "Cannot initialize array containing references");
858 mono_raise_exception (exc
);
861 if (!(field_handle
->type
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) {
862 MonoException
*exc
= mono_get_exception_argument("field_handle",
863 "Field doesn't have an RVA");
864 mono_raise_exception (exc
);
867 size
*= array
->max_length
;
868 field_data
= mono_field_get_data (field_handle
);
870 if (size
> mono_type_size (field_handle
->type
, &align
)) {
871 MonoException
*exc
= mono_get_exception_argument("field_handle",
872 "Field not large enough to fill array");
873 mono_raise_exception (exc
);
876 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
878 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
879 guint ## n *src = (guint ## n *) field_data; \
880 guint ## n *end = (guint ## n *)((char*)src + size); \
882 for (; src < end; data++, src++) { \
883 *data = read ## n (src); \
887 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
889 switch (type
->type
) {
906 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
910 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
912 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_R8
) {
915 double *data
= (double*)mono_array_addr (array
, double, 0);
917 for (i
= 0; i
< size
; i
++, data
++) {
927 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
931 return offsetof (MonoString
, chars
);
935 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject
*obj
)
939 if ((obj
== NULL
) || (! (obj
->vtable
->klass
->valuetype
)))
942 return mono_object_clone (obj
);
946 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType
*handle
)
951 MONO_CHECK_ARG_NULL (handle
);
953 klass
= mono_class_from_mono_type (handle
);
954 MONO_CHECK_ARG (handle
, klass
);
956 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, TRUE
);
958 /* This will call the type constructor */
959 mono_runtime_class_init (vtable
);
963 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage
*image
)
967 mono_image_check_for_module_cctor (image
);
968 if (image
->has_module_cctor
) {
969 MonoClass
*module_klass
= mono_class_get (image
, MONO_TOKEN_TYPE_DEF
| 1);
970 /*It's fine to raise the exception here*/
971 mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass
, TRUE
));
976 ves_icall_System_Object_MemberwiseClone (MonoObject
*this)
980 return mono_object_clone (this);
984 ves_icall_System_ValueType_InternalGetHashCode (MonoObject
*this, MonoArray
**fields
)
987 MonoObject
**values
= NULL
;
991 MonoClassField
* field
;
996 klass
= mono_object_class (this);
998 if (mono_class_num_fields (klass
) == 0)
999 return mono_object_hash (this);
1002 * Compute the starting value of the hashcode for fields of primitive
1003 * types, and return the remaining fields in an array to the managed side.
1004 * This way, we can avoid costly reflection operations in managed code.
1007 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1008 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1010 if (mono_field_is_deleted (field
))
1012 /* FIXME: Add more types */
1013 switch (field
->type
->type
) {
1015 result
^= *(gint32
*)((guint8
*)this + field
->offset
);
1017 case MONO_TYPE_STRING
: {
1019 s
= *(MonoString
**)((guint8
*)this + field
->offset
);
1021 result
^= mono_string_hash (s
);
1026 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
));
1027 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1028 values
[count
++] = o
;
1034 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
));
1035 for (i
= 0; i
< count
; ++i
)
1036 mono_array_setref (*fields
, i
, values
[i
]);
1044 ves_icall_System_ValueType_Equals (MonoObject
*this, MonoObject
*that
, MonoArray
**fields
)
1047 MonoObject
**values
= NULL
;
1049 MonoClassField
* field
;
1053 MONO_ARCH_SAVE_REGS
;
1055 MONO_CHECK_ARG_NULL (that
);
1057 if (this->vtable
!= that
->vtable
)
1060 klass
= mono_object_class (this);
1062 if (klass
->enumtype
&& mono_class_enum_basetype (klass
) && mono_class_enum_basetype (klass
)->type
== MONO_TYPE_I4
)
1063 return (*(gint32
*)((guint8
*)this + sizeof (MonoObject
)) == *(gint32
*)((guint8
*)that
+ sizeof (MonoObject
)));
1066 * Do the comparison for fields of primitive type and return a result if
1067 * possible. Otherwise, return the remaining fields in an array to the
1068 * managed side. This way, we can avoid costly reflection operations in
1073 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1074 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1076 if (mono_field_is_deleted (field
))
1078 /* FIXME: Add more types */
1079 switch (field
->type
->type
) {
1082 case MONO_TYPE_BOOLEAN
:
1083 if (*((guint8
*)this + field
->offset
) != *((guint8
*)that
+ field
->offset
))
1088 case MONO_TYPE_CHAR
:
1089 if (*(gint16
*)((guint8
*)this + field
->offset
) != *(gint16
*)((guint8
*)that
+ field
->offset
))
1094 if (*(gint32
*)((guint8
*)this + field
->offset
) != *(gint32
*)((guint8
*)that
+ field
->offset
))
1099 if (*(gint64
*)((guint8
*)this + field
->offset
) != *(gint64
*)((guint8
*)that
+ field
->offset
))
1103 if (*(float*)((guint8
*)this + field
->offset
) != *(float*)((guint8
*)that
+ field
->offset
))
1107 if (*(double*)((guint8
*)this + field
->offset
) != *(double*)((guint8
*)that
+ field
->offset
))
1112 case MONO_TYPE_STRING
: {
1113 MonoString
*s1
, *s2
;
1114 guint32 s1len
, s2len
;
1115 s1
= *(MonoString
**)((guint8
*)this + field
->offset
);
1116 s2
= *(MonoString
**)((guint8
*)that
+ field
->offset
);
1119 if ((s1
== NULL
) || (s2
== NULL
))
1121 s1len
= mono_string_length (s1
);
1122 s2len
= mono_string_length (s2
);
1126 if (memcmp (mono_string_chars (s1
), mono_string_chars (s2
), s1len
* sizeof (gunichar2
)) != 0)
1132 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
) * 2);
1133 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1134 values
[count
++] = o
;
1135 o
= mono_field_get_value_object (mono_object_domain (this), field
, that
);
1136 values
[count
++] = o
;
1139 if (klass
->enumtype
)
1140 /* enums only have one non-static field */
1146 mono_gc_wbarrier_generic_store (fields
, (MonoObject
*) mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
));
1147 for (i
= 0; i
< count
; ++i
)
1148 mono_array_setref (*fields
, i
, values
[i
]);
1155 static MonoReflectionType
*
1156 ves_icall_System_Object_GetType (MonoObject
*obj
)
1158 MONO_ARCH_SAVE_REGS
;
1160 if (obj
->vtable
->klass
!= mono_defaults
.transparent_proxy_class
)
1161 return mono_type_get_object (mono_object_domain (obj
), &obj
->vtable
->klass
->byval_arg
);
1163 return mono_type_get_object (mono_object_domain (obj
), &((MonoTransparentProxy
*)obj
)->remote_class
->proxy_class
->byval_arg
);
1167 mono_type_type_from_obj (MonoReflectionType
*mtype
, MonoObject
*obj
)
1169 MONO_ARCH_SAVE_REGS
;
1171 mtype
->type
= &obj
->vtable
->klass
->byval_arg
;
1172 g_assert (mtype
->type
->type
);
1176 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
)
1178 MONO_ARCH_SAVE_REGS
;
1180 MONO_CHECK_ARG_NULL (obj
);
1182 return mono_image_create_token (mb
->dynamic_image
, obj
, TRUE
, TRUE
);
1186 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder
*mb
,
1187 MonoReflectionMethod
*method
,
1188 MonoArray
*opt_param_types
)
1190 MONO_ARCH_SAVE_REGS
;
1192 MONO_CHECK_ARG_NULL (method
);
1194 return mono_image_create_method_token (
1195 mb
->dynamic_image
, (MonoObject
*) method
, opt_param_types
);
1199 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
1201 MONO_ARCH_SAVE_REGS
;
1203 mono_image_create_pefile (mb
, file
);
1207 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
1209 MONO_ARCH_SAVE_REGS
;
1211 mono_image_build_metadata (mb
);
1215 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, guint32 token
)
1217 MONO_ARCH_SAVE_REGS
;
1219 mono_image_register_token (mb
->dynamic_image
, token
, obj
);
1223 get_caller (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1225 MonoMethod
**dest
= data
;
1227 /* skip unmanaged frames */
1243 get_executing (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1245 MonoMethod
**dest
= data
;
1247 /* skip unmanaged frames */
1252 if (!strcmp (m
->klass
->name_space
, "System.Reflection"))
1261 get_caller_no_reflection (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1263 MonoMethod
**dest
= data
;
1265 /* skip unmanaged frames */
1269 if (m
->wrapper_type
!= MONO_WRAPPER_NONE
)
1272 if (m
->klass
->image
== mono_defaults
.corlib
&& !strcmp (m
->klass
->name_space
, "System.Reflection"))
1286 static MonoReflectionType
*
1287 type_from_name (const char *str
, MonoBoolean ignoreCase
)
1289 MonoType
*type
= NULL
;
1290 MonoAssembly
*assembly
= NULL
;
1291 MonoTypeNameParse info
;
1292 char *temp_str
= g_strdup (str
);
1293 gboolean type_resolve
= FALSE
;
1295 MONO_ARCH_SAVE_REGS
;
1297 /* mono_reflection_parse_type() mangles the string */
1298 if (!mono_reflection_parse_type (temp_str
, &info
)) {
1299 mono_reflection_free_type_info (&info
);
1304 if (info
.assembly
.name
) {
1305 assembly
= mono_assembly_load (&info
.assembly
, NULL
, NULL
);
1307 MonoMethod
*m
= mono_method_get_last_managed ();
1308 MonoMethod
*dest
= m
;
1310 mono_stack_walk_no_il (get_caller_no_reflection
, &dest
);
1315 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1316 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1317 * to crash. This only seems to happen in some strange remoting
1318 * scenarios and I was unable to figure out what's happening there.
1319 * Dec 10, 2005 - Martin.
1323 assembly
= dest
->klass
->image
->assembly
;
1325 g_warning (G_STRLOC
);
1330 type
= mono_reflection_get_type (assembly
->image
, &info
, ignoreCase
, &type_resolve
);
1332 if (!info
.assembly
.name
&& !type
) /* try mscorlib */
1333 type
= mono_reflection_get_type (NULL
, &info
, ignoreCase
, &type_resolve
);
1335 mono_reflection_free_type_info (&info
);
1341 return mono_type_get_object (mono_domain_get (), type
);
1345 MonoReflectionType
*
1346 mono_type_get (const char *str
)
1348 char *copy
= g_strdup (str
);
1349 MonoReflectionType
*type
= type_from_name (copy
, FALSE
);
1356 static MonoReflectionType
*
1357 ves_icall_type_from_name (MonoString
*name
,
1358 MonoBoolean throwOnError
,
1359 MonoBoolean ignoreCase
)
1361 char *str
= mono_string_to_utf8 (name
);
1362 MonoReflectionType
*type
;
1364 type
= type_from_name (str
, ignoreCase
);
1367 MonoException
*e
= NULL
;
1370 e
= mono_get_exception_type_load (name
, NULL
);
1372 mono_loader_clear_error ();
1374 mono_raise_exception (e
);
1381 static MonoReflectionType
*
1382 ves_icall_type_from_handle (MonoType
*handle
)
1384 MonoDomain
*domain
= mono_domain_get ();
1385 MonoClass
*klass
= mono_class_from_mono_type (handle
);
1387 MONO_ARCH_SAVE_REGS
;
1389 mono_class_init (klass
);
1390 return mono_type_get_object (domain
, handle
);
1394 ves_icall_System_Type_EqualsInternal (MonoReflectionType
*type
, MonoReflectionType
*c
)
1396 MONO_ARCH_SAVE_REGS
;
1398 if (c
&& type
->type
&& c
->type
)
1399 return mono_metadata_type_equal (type
->type
, c
->type
);
1401 return (type
== c
) ? TRUE
: FALSE
;
1404 /* System.TypeCode */
1423 TYPECODE_STRING
= 18
1427 ves_icall_type_GetTypeCodeInternal (MonoReflectionType
*type
)
1429 int t
= type
->type
->type
;
1431 MONO_ARCH_SAVE_REGS
;
1433 if (type
->type
->byref
)
1434 return TYPECODE_OBJECT
;
1438 case MONO_TYPE_VOID
:
1439 return TYPECODE_OBJECT
;
1440 case MONO_TYPE_BOOLEAN
:
1441 return TYPECODE_BOOLEAN
;
1443 return TYPECODE_BYTE
;
1445 return TYPECODE_SBYTE
;
1447 return TYPECODE_UINT16
;
1449 return TYPECODE_INT16
;
1450 case MONO_TYPE_CHAR
:
1451 return TYPECODE_CHAR
;
1455 return TYPECODE_OBJECT
;
1457 return TYPECODE_UINT32
;
1459 return TYPECODE_INT32
;
1461 return TYPECODE_UINT64
;
1463 return TYPECODE_INT64
;
1465 return TYPECODE_SINGLE
;
1467 return TYPECODE_DOUBLE
;
1468 case MONO_TYPE_VALUETYPE
:
1469 if (type
->type
->data
.klass
->enumtype
) {
1470 t
= mono_class_enum_basetype (type
->type
->data
.klass
)->type
;
1473 MonoClass
*k
= type
->type
->data
.klass
;
1474 if (strcmp (k
->name_space
, "System") == 0) {
1475 if (strcmp (k
->name
, "Decimal") == 0)
1476 return TYPECODE_DECIMAL
;
1477 else if (strcmp (k
->name
, "DateTime") == 0)
1478 return TYPECODE_DATETIME
;
1481 return TYPECODE_OBJECT
;
1482 case MONO_TYPE_STRING
:
1483 return TYPECODE_STRING
;
1484 case MONO_TYPE_SZARRAY
:
1485 case MONO_TYPE_ARRAY
:
1486 case MONO_TYPE_OBJECT
:
1488 case MONO_TYPE_MVAR
:
1489 case MONO_TYPE_TYPEDBYREF
:
1490 return TYPECODE_OBJECT
;
1491 case MONO_TYPE_CLASS
:
1493 MonoClass
*k
= type
->type
->data
.klass
;
1494 if (strcmp (k
->name_space
, "System") == 0) {
1495 if (strcmp (k
->name
, "DBNull") == 0)
1496 return TYPECODE_DBNULL
;
1499 return TYPECODE_OBJECT
;
1500 case MONO_TYPE_GENERICINST
:
1501 return TYPECODE_OBJECT
;
1503 g_error ("type 0x%02x not handled in GetTypeCode()", t
);
1509 ves_icall_type_is_subtype_of (MonoReflectionType
*type
, MonoReflectionType
*c
, MonoBoolean check_interfaces
)
1515 MONO_ARCH_SAVE_REGS
;
1517 g_assert (type
!= NULL
);
1519 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1521 if (!c
) /* FIXME: dont know what do do here */
1524 klass
= mono_class_from_mono_type (type
->type
);
1525 klassc
= mono_class_from_mono_type (c
->type
);
1527 if (type
->type
->byref
)
1528 return klassc
== mono_defaults
.object_class
;
1530 return mono_class_is_subclass_of (klass
, klassc
, check_interfaces
);
1534 ves_icall_type_is_assignable_from (MonoReflectionType
*type
, MonoReflectionType
*c
)
1540 MONO_ARCH_SAVE_REGS
;
1542 g_assert (type
!= NULL
);
1544 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1546 klass
= mono_class_from_mono_type (type
->type
);
1547 klassc
= mono_class_from_mono_type (c
->type
);
1549 if (type
->type
->byref
&& !c
->type
->byref
)
1552 return mono_class_is_assignable_from (klass
, klassc
);
1556 ves_icall_type_IsInstanceOfType (MonoReflectionType
*type
, MonoObject
*obj
)
1558 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1559 return mono_object_isinst (obj
, klass
) != NULL
;
1563 ves_icall_get_attributes (MonoReflectionType
*type
)
1565 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1567 MONO_ARCH_SAVE_REGS
;
1569 return klass
->flags
;
1572 static MonoReflectionMarshal
*
1573 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField
*field
)
1575 MonoClass
*klass
= field
->field
->parent
;
1576 MonoMarshalType
*info
;
1579 if (klass
->generic_container
||
1580 (klass
->generic_class
&& klass
->generic_class
->context
.class_inst
->is_open
))
1583 info
= mono_marshal_load_type_info (klass
);
1585 for (i
= 0; i
< info
->num_fields
; ++i
) {
1586 if (info
->fields
[i
].field
== field
->field
) {
1587 if (!info
->fields
[i
].mspec
)
1590 return mono_reflection_marshal_from_marshal_spec (field
->object
.vtable
->domain
, klass
, info
->fields
[i
].mspec
);
1597 static MonoReflectionField
*
1598 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
*handle
, MonoType
*type
)
1600 gboolean found
= FALSE
;
1607 klass
= handle
->parent
;
1609 klass
= mono_class_from_mono_type (type
);
1611 /* Check that the field belongs to the class */
1612 for (k
= klass
; k
; k
= k
->parent
) {
1613 if (k
== handle
->parent
) {
1620 /* The managed code will throw the exception */
1624 return mono_field_get_object (mono_domain_get (), klass
, handle
);
1628 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField
*field
, MonoBoolean optional
)
1630 MonoType
*type
= field
->field
->type
;
1632 return type_array_from_modifiers (field
->field
->parent
->image
, type
, optional
);
1636 ves_icall_get_method_info (MonoMethod
*method
, MonoMethodInfo
*info
)
1638 MonoDomain
*domain
= mono_domain_get ();
1639 MonoMethodSignature
* sig
;
1640 MONO_ARCH_SAVE_REGS
;
1642 sig
= mono_method_signature (method
);
1644 g_assert (mono_loader_get_last_error ());
1645 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1648 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &method
->klass
->byval_arg
));
1649 MONO_STRUCT_SETREF (info
, ret
, mono_type_get_object (domain
, sig
->ret
));
1650 info
->attrs
= method
->flags
;
1651 info
->implattrs
= method
->iflags
;
1652 if (sig
->call_convention
== MONO_CALL_DEFAULT
)
1653 info
->callconv
= sig
->sentinelpos
>= 0 ? 2 : 1;
1655 if (sig
->call_convention
== MONO_CALL_VARARG
|| sig
->sentinelpos
>= 0)
1660 info
->callconv
|= (sig
->hasthis
<< 5) | (sig
->explicit_this
<< 6);
1664 ves_icall_get_parameter_info (MonoMethod
*method
, MonoReflectionMethod
*member
)
1666 MonoDomain
*domain
= mono_domain_get ();
1668 return mono_param_get_objects_internal (domain
, method
, member
->reftype
? mono_class_from_mono_type (member
->reftype
->type
) : NULL
);
1671 static MonoReflectionMarshal
*
1672 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod
*method
)
1674 MonoDomain
*domain
= mono_domain_get ();
1675 MonoReflectionMarshal
* res
= NULL
;
1676 MonoMarshalSpec
**mspecs
;
1679 mspecs
= g_new (MonoMarshalSpec
*, mono_method_signature (method
)->param_count
+ 1);
1680 mono_method_get_marshal_info (method
, mspecs
);
1683 res
= mono_reflection_marshal_from_marshal_spec (domain
, method
->klass
, mspecs
[0]);
1685 for (i
= mono_method_signature (method
)->param_count
; i
>= 0; i
--)
1687 mono_metadata_free_marshal_spec (mspecs
[i
]);
1694 ves_icall_MonoField_GetFieldOffset (MonoReflectionField
*field
)
1696 return field
->field
->offset
- sizeof (MonoObject
);
1699 static MonoReflectionType
*
1700 ves_icall_MonoField_GetParentType (MonoReflectionField
*field
, MonoBoolean declaring
)
1703 MONO_ARCH_SAVE_REGS
;
1705 parent
= declaring
? field
->field
->parent
: field
->klass
;
1707 return mono_type_get_object (mono_object_domain (field
), &parent
->byval_arg
);
1711 ves_icall_MonoField_GetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
)
1714 MonoClassField
*cf
= field
->field
;
1718 MonoDomain
*domain
= mono_object_domain (field
);
1720 gboolean is_static
= FALSE
;
1721 gboolean is_ref
= FALSE
;
1723 MONO_ARCH_SAVE_REGS
;
1725 if (field
->klass
->image
->assembly
->ref_only
)
1726 mono_raise_exception (mono_get_exception_invalid_operation (
1727 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1729 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
1730 mono_security_core_clr_ensure_reflection_access_field (cf
);
1732 mono_class_init (field
->klass
);
1734 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1737 if (obj
&& !is_static
) {
1738 /* Check that the field belongs to the object */
1739 gboolean found
= FALSE
;
1742 for (k
= obj
->vtable
->klass
; k
; k
= k
->parent
) {
1743 if (k
== cf
->parent
) {
1750 char *msg
= g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf
), cf
->parent
->name
, obj
->vtable
->klass
->name
);
1751 MonoException
*ex
= mono_get_exception_argument (NULL
, msg
);
1753 mono_raise_exception (ex
);
1757 t
= mono_type_get_underlying_type (cf
->type
);
1759 case MONO_TYPE_STRING
:
1760 case MONO_TYPE_OBJECT
:
1761 case MONO_TYPE_CLASS
:
1762 case MONO_TYPE_ARRAY
:
1763 case MONO_TYPE_SZARRAY
:
1768 case MONO_TYPE_BOOLEAN
:
1771 case MONO_TYPE_CHAR
:
1780 case MONO_TYPE_VALUETYPE
:
1783 case MONO_TYPE_GENERICINST
:
1784 if (mono_type_generic_inst_is_valuetype (t
)) {
1791 g_error ("type 0x%x not handled in "
1792 "ves_icall_Monofield_GetValue", t
->type
);
1798 vtable
= mono_class_vtable_full (domain
, cf
->parent
, TRUE
);
1799 if (!vtable
->initialized
&& !(cf
->type
->attrs
& FIELD_ATTRIBUTE_LITERAL
))
1800 mono_runtime_class_init (vtable
);
1805 mono_field_static_get_value (vtable
, cf
, &o
);
1807 mono_field_get_value (obj
, cf
, &o
);
1812 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1813 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1816 /* Convert the Nullable structure into a boxed vtype */
1818 buf
= (guint8
*)vtable
->data
+ cf
->offset
;
1820 buf
= (guint8
*)obj
+ cf
->offset
;
1822 return mono_nullable_box (buf
, nklass
);
1825 /* boxed value type */
1826 klass
= mono_class_from_mono_type (cf
->type
);
1827 o
= mono_object_new (domain
, klass
);
1828 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1830 mono_field_static_get_value (vtable
, cf
, v
);
1832 mono_field_get_value (obj
, cf
, v
);
1839 ves_icall_MonoField_SetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
, MonoObject
*value
)
1841 MonoClassField
*cf
= field
->field
;
1844 MONO_ARCH_SAVE_REGS
;
1846 if (field
->klass
->image
->assembly
->ref_only
)
1847 mono_raise_exception (mono_get_exception_invalid_operation (
1848 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1850 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
1851 mono_security_core_clr_ensure_reflection_access_field (cf
);
1853 v
= (gchar
*) value
;
1854 if (!cf
->type
->byref
) {
1855 switch (cf
->type
->type
) {
1858 case MONO_TYPE_BOOLEAN
:
1861 case MONO_TYPE_CHAR
:
1870 case MONO_TYPE_VALUETYPE
:
1872 v
+= sizeof (MonoObject
);
1874 case MONO_TYPE_STRING
:
1875 case MONO_TYPE_OBJECT
:
1876 case MONO_TYPE_CLASS
:
1877 case MONO_TYPE_ARRAY
:
1878 case MONO_TYPE_SZARRAY
:
1881 case MONO_TYPE_GENERICINST
: {
1882 MonoGenericClass
*gclass
= cf
->type
->data
.generic_class
;
1883 g_assert (!gclass
->context
.class_inst
->is_open
);
1885 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1886 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1887 MonoObject
*nullable
;
1890 * Convert the boxed vtype into a Nullable structure.
1891 * This is complicated by the fact that Nullables have
1892 * a variable structure.
1894 nullable
= mono_object_new (mono_domain_get (), nklass
);
1896 mono_nullable_init (mono_object_unbox (nullable
), value
, nklass
);
1898 v
= mono_object_unbox (nullable
);
1901 if (gclass
->container_class
->valuetype
&& (v
!= NULL
))
1902 v
+= sizeof (MonoObject
);
1906 g_error ("type 0x%x not handled in "
1907 "ves_icall_FieldInfo_SetValueInternal", cf
->type
->type
);
1912 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
1913 MonoVTable
*vtable
= mono_class_vtable_full (mono_object_domain (field
), cf
->parent
, TRUE
);
1914 if (!vtable
->initialized
)
1915 mono_runtime_class_init (vtable
);
1916 mono_field_static_set_value (vtable
, cf
, v
);
1918 mono_field_set_value (obj
, cf
, v
);
1923 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField
*this)
1925 MonoObject
*o
= NULL
;
1926 MonoClassField
*field
= this->field
;
1928 MonoDomain
*domain
= mono_object_domain (this);
1930 MonoTypeEnum def_type
;
1931 const char *def_value
;
1933 MONO_ARCH_SAVE_REGS
;
1935 mono_class_init (field
->parent
);
1937 if (!(field
->type
->attrs
& FIELD_ATTRIBUTE_HAS_DEFAULT
))
1938 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
1940 if (field
->parent
->image
->dynamic
) {
1942 g_assert_not_reached ();
1945 def_value
= mono_class_get_field_default_value (field
, &def_type
);
1950 case MONO_TYPE_BOOLEAN
:
1953 case MONO_TYPE_CHAR
:
1961 case MONO_TYPE_R8
: {
1964 /* boxed value type */
1965 t
= g_new0 (MonoType
, 1);
1967 klass
= mono_class_from_mono_type (t
);
1969 o
= mono_object_new (domain
, klass
);
1970 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1971 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, v
);
1974 case MONO_TYPE_STRING
:
1975 case MONO_TYPE_CLASS
:
1976 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, &o
);
1979 g_assert_not_reached ();
1985 static MonoReflectionType
*
1986 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod
*rmethod
)
1988 MonoMethod
*method
= rmethod
->method
.method
;
1990 return mono_type_get_object (mono_object_domain (rmethod
), &method
->klass
->byval_arg
);
1993 /* From MonoProperty.cs */
1995 PInfo_Attributes
= 1,
1996 PInfo_GetMethod
= 1 << 1,
1997 PInfo_SetMethod
= 1 << 2,
1998 PInfo_ReflectedType
= 1 << 3,
1999 PInfo_DeclaringType
= 1 << 4,
2004 ves_icall_get_property_info (MonoReflectionProperty
*property
, MonoPropertyInfo
*info
, PInfo req_info
)
2006 MonoDomain
*domain
= mono_object_domain (property
);
2008 MONO_ARCH_SAVE_REGS
;
2010 if ((req_info
& PInfo_ReflectedType
) != 0)
2011 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->klass
->byval_arg
));
2012 else if ((req_info
& PInfo_DeclaringType
) != 0)
2013 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->property
->parent
->byval_arg
));
2015 if ((req_info
& PInfo_Name
) != 0)
2016 MONO_STRUCT_SETREF (info
, name
, mono_string_new (domain
, property
->property
->name
));
2018 if ((req_info
& PInfo_Attributes
) != 0)
2019 info
->attrs
= property
->property
->attrs
;
2021 if ((req_info
& PInfo_GetMethod
) != 0)
2022 MONO_STRUCT_SETREF (info
, get
, property
->property
->get
?
2023 mono_method_get_object (domain
, property
->property
->get
, property
->klass
): NULL
);
2025 if ((req_info
& PInfo_SetMethod
) != 0)
2026 MONO_STRUCT_SETREF (info
, set
, property
->property
->set
?
2027 mono_method_get_object (domain
, property
->property
->set
, property
->klass
): NULL
);
2029 * There may be other methods defined for properties, though, it seems they are not exposed
2030 * in the reflection API
2035 ves_icall_get_event_info (MonoReflectionMonoEvent
*event
, MonoEventInfo
*info
)
2037 MonoDomain
*domain
= mono_object_domain (event
);
2039 MONO_ARCH_SAVE_REGS
;
2041 MONO_STRUCT_SETREF (info
, reflected_type
, mono_type_get_object (domain
, &event
->klass
->byval_arg
));
2042 MONO_STRUCT_SETREF (info
, declaring_type
, mono_type_get_object (domain
, &event
->event
->parent
->byval_arg
));
2044 MONO_STRUCT_SETREF (info
, name
, mono_string_new (domain
, event
->event
->name
));
2045 info
->attrs
= event
->event
->attrs
;
2046 MONO_STRUCT_SETREF (info
, add_method
, event
->event
->add
? mono_method_get_object (domain
, event
->event
->add
, NULL
): NULL
);
2047 MONO_STRUCT_SETREF (info
, remove_method
, event
->event
->remove
? mono_method_get_object (domain
, event
->event
->remove
, NULL
): NULL
);
2048 MONO_STRUCT_SETREF (info
, raise_method
, event
->event
->raise
? mono_method_get_object (domain
, event
->event
->raise
, NULL
): NULL
);
2050 if (event
->event
->other
) {
2052 while (event
->event
->other
[n
])
2054 MONO_STRUCT_SETREF (info
, other_methods
, mono_array_new (domain
, mono_defaults
.method_info_class
, n
));
2056 for (i
= 0; i
< n
; i
++)
2057 mono_array_setref (info
->other_methods
, i
, mono_method_get_object (domain
, event
->event
->other
[i
], NULL
));
2062 ves_icall_Type_GetInterfaces (MonoReflectionType
* type
)
2065 MonoDomain
*domain
= mono_object_domain (type
);
2067 GPtrArray
*ifaces
= NULL
;
2069 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2072 MonoGenericContext
*context
= NULL
;
2074 MONO_ARCH_SAVE_REGS
;
2076 if (class->generic_class
&& class->generic_class
->context
.class_inst
->is_open
) {
2077 context
= mono_class_get_context (class);
2078 class = class->generic_class
->container_class
;
2081 mono_class_setup_vtable (class);
2083 slots
= mono_bitset_new (class->max_interface_id
+ 1, 0);
2085 for (parent
= class; parent
; parent
= parent
->parent
) {
2086 GPtrArray
*tmp_ifaces
= mono_class_get_implemented_interfaces (parent
, &error
);
2087 if (!mono_error_ok (&error
)) {
2088 mono_bitset_free (slots
);
2089 mono_error_raise_exception (&error
);
2091 } else if (tmp_ifaces
) {
2092 for (i
= 0; i
< tmp_ifaces
->len
; ++i
) {
2093 MonoClass
*ic
= g_ptr_array_index (tmp_ifaces
, i
);
2095 if (mono_bitset_test (slots
, ic
->interface_id
))
2098 mono_bitset_set (slots
, ic
->interface_id
);
2100 ifaces
= g_ptr_array_new ();
2101 g_ptr_array_add (ifaces
, ic
);
2103 g_ptr_array_free (tmp_ifaces
, TRUE
);
2106 mono_bitset_free (slots
);
2109 return mono_array_new_cached (domain
, mono_defaults
.monotype_class
, 0);
2111 intf
= mono_array_new_cached (domain
, mono_defaults
.monotype_class
, ifaces
->len
);
2112 for (i
= 0; i
< ifaces
->len
; ++i
) {
2113 MonoClass
*ic
= g_ptr_array_index (ifaces
, i
);
2114 MonoType
*ret
= &ic
->byval_arg
, *inflated
= NULL
;
2115 if (context
&& ic
->generic_class
&& ic
->generic_class
->context
.class_inst
->is_open
)
2116 inflated
= ret
= mono_class_inflate_generic_type (ret
, context
);
2118 mono_array_setref (intf
, i
, mono_type_get_object (domain
, ret
));
2120 mono_metadata_free_type (inflated
);
2122 g_ptr_array_free (ifaces
, TRUE
);
2128 ves_icall_Type_GetInterfaceMapData (MonoReflectionType
*type
, MonoReflectionType
*iface
, MonoArray
**targets
, MonoArray
**methods
)
2130 gboolean variance_used
;
2131 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2132 MonoClass
*iclass
= mono_class_from_mono_type (iface
->type
);
2133 MonoReflectionMethod
*member
;
2136 int i
= 0, len
, ioffset
;
2139 MONO_ARCH_SAVE_REGS
;
2141 mono_class_setup_vtable (class);
2143 ioffset
= mono_class_interface_offset_with_variance (class, iclass
, &variance_used
);
2147 len
= mono_class_num_methods (iclass
);
2148 domain
= mono_object_domain (type
);
2149 mono_gc_wbarrier_generic_store (targets
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.method_info_class
, len
));
2150 mono_gc_wbarrier_generic_store (methods
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.method_info_class
, len
));
2152 while ((method
= mono_class_get_methods (iclass
, &iter
))) {
2153 member
= mono_method_get_object (domain
, method
, iclass
);
2154 mono_array_setref (*methods
, i
, member
);
2155 member
= mono_method_get_object (domain
, class->vtable
[i
+ ioffset
], class);
2156 mono_array_setref (*targets
, i
, member
);
2163 ves_icall_Type_GetPacking (MonoReflectionType
*type
, guint32
*packing
, guint32
*size
)
2165 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2167 if (klass
->image
->dynamic
) {
2168 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)type
;
2169 *packing
= tb
->packing_size
;
2170 *size
= tb
->class_size
;
2172 mono_metadata_packing_from_typedef (klass
->image
, klass
->type_token
, packing
, size
);
2176 static MonoReflectionType
*
2177 ves_icall_MonoType_GetElementType (MonoReflectionType
*type
)
2181 MONO_ARCH_SAVE_REGS
;
2183 if (!type
->type
->byref
&& type
->type
->type
== MONO_TYPE_SZARRAY
)
2184 return mono_type_get_object (mono_object_domain (type
), &type
->type
->data
.klass
->byval_arg
);
2186 class = mono_class_from_mono_type (type
->type
);
2188 // GetElementType should only return a type for:
2189 // Array Pointer PassedByRef
2190 if (type
->type
->byref
)
2191 return mono_type_get_object (mono_object_domain (type
), &class->byval_arg
);
2192 else if (class->element_class
&& MONO_CLASS_IS_ARRAY (class))
2193 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2194 else if (class->element_class
&& type
->type
->type
== MONO_TYPE_PTR
)
2195 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2200 static MonoReflectionType
*
2201 ves_icall_get_type_parent (MonoReflectionType
*type
)
2203 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2205 MONO_ARCH_SAVE_REGS
;
2207 return class->parent
? mono_type_get_object (mono_object_domain (type
), &class->parent
->byval_arg
): NULL
;
2211 ves_icall_type_ispointer (MonoReflectionType
*type
)
2213 MONO_ARCH_SAVE_REGS
;
2215 return type
->type
->type
== MONO_TYPE_PTR
;
2219 ves_icall_type_isprimitive (MonoReflectionType
*type
)
2221 MONO_ARCH_SAVE_REGS
;
2223 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
)));
2227 ves_icall_type_isbyref (MonoReflectionType
*type
)
2229 MONO_ARCH_SAVE_REGS
;
2231 return type
->type
->byref
;
2235 ves_icall_type_iscomobject (MonoReflectionType
*type
)
2237 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2238 MONO_ARCH_SAVE_REGS
;
2240 return (klass
&& klass
->is_com_object
);
2243 static MonoReflectionModule
*
2244 ves_icall_MonoType_get_Module (MonoReflectionType
*type
)
2246 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2248 MONO_ARCH_SAVE_REGS
;
2250 return mono_module_get_object (mono_object_domain (type
), class->image
);
2253 static MonoReflectionAssembly
*
2254 ves_icall_MonoType_get_Assembly (MonoReflectionType
*type
)
2256 MonoDomain
*domain
= mono_domain_get ();
2257 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2259 MONO_ARCH_SAVE_REGS
;
2261 return mono_assembly_get_object (domain
, class->image
->assembly
);
2264 static MonoReflectionType
*
2265 ves_icall_MonoType_get_DeclaringType (MonoReflectionType
*type
)
2267 MonoDomain
*domain
= mono_domain_get ();
2270 MONO_ARCH_SAVE_REGS
;
2272 if (type
->type
->byref
)
2274 if (type
->type
->type
== MONO_TYPE_VAR
)
2275 class = mono_type_get_generic_param_owner (type
->type
)->owner
.klass
;
2276 else if (type
->type
->type
== MONO_TYPE_MVAR
)
2277 class = mono_type_get_generic_param_owner (type
->type
)->owner
.method
->klass
;
2279 class = mono_class_from_mono_type (type
->type
)->nested_in
;
2281 return class ? mono_type_get_object (domain
, &class->byval_arg
) : NULL
;
2284 static MonoReflectionType
*
2285 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType
*type
)
2287 MonoDomain
*domain
= mono_domain_get ();
2288 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2290 MONO_ARCH_SAVE_REGS
;
2292 if (class->enumtype
&& mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
2293 return mono_type_get_object (domain
, mono_class_enum_basetype (class));
2294 else if (class->element_class
)
2295 return mono_type_get_object (domain
, &class->element_class
->byval_arg
);
2301 ves_icall_MonoType_get_Name (MonoReflectionType
*type
)
2303 MonoDomain
*domain
= mono_domain_get ();
2304 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2306 MONO_ARCH_SAVE_REGS
;
2308 if (type
->type
->byref
) {
2309 char *n
= g_strdup_printf ("%s&", class->name
);
2310 MonoString
*res
= mono_string_new (domain
, n
);
2316 return mono_string_new (domain
, class->name
);
2321 ves_icall_MonoType_get_Namespace (MonoReflectionType
*type
)
2323 MonoDomain
*domain
= mono_domain_get ();
2324 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2326 MONO_ARCH_SAVE_REGS
;
2328 while (class->nested_in
)
2329 class = class->nested_in
;
2331 if (class->name_space
[0] == '\0')
2334 return mono_string_new (domain
, class->name_space
);
2338 ves_icall_MonoType_GetArrayRank (MonoReflectionType
*type
)
2342 if (type
->type
->type
!= MONO_TYPE_ARRAY
&& type
->type
->type
!= MONO_TYPE_SZARRAY
)
2343 mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2345 class = mono_class_from_mono_type (type
->type
);
2350 ves_icall_MonoType_GetGenericArguments (MonoReflectionType
*type
)
2353 MonoClass
*klass
, *pklass
;
2354 MonoDomain
*domain
= mono_object_domain (type
);
2355 MonoVTable
*array_vtable
= mono_class_vtable_full (domain
, mono_array_class_get_cached (mono_defaults
.systemtype_class
, 1), TRUE
);
2357 MONO_ARCH_SAVE_REGS
;
2359 klass
= mono_class_from_mono_type (type
->type
);
2361 if (klass
->generic_container
) {
2362 MonoGenericContainer
*container
= klass
->generic_container
;
2363 res
= mono_array_new_specific (array_vtable
, container
->type_argc
);
2364 for (i
= 0; i
< container
->type_argc
; ++i
) {
2365 pklass
= mono_class_from_generic_parameter (mono_generic_container_get_param (container
, i
), klass
->image
, FALSE
);
2366 mono_array_setref (res
, i
, mono_type_get_object (domain
, &pklass
->byval_arg
));
2368 } else if (klass
->generic_class
) {
2369 MonoGenericInst
*inst
= klass
->generic_class
->context
.class_inst
;
2370 res
= mono_array_new_specific (array_vtable
, inst
->type_argc
);
2371 for (i
= 0; i
< inst
->type_argc
; ++i
)
2372 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2374 res
= mono_array_new_specific (array_vtable
, 0);
2380 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType
*type
)
2383 MONO_ARCH_SAVE_REGS
;
2385 if (!IS_MONOTYPE (type
))
2388 if (type
->type
->byref
)
2391 klass
= mono_class_from_mono_type (type
->type
);
2393 return klass
->generic_container
!= NULL
;
2396 static MonoReflectionType
*
2397 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType
*type
)
2400 MONO_ARCH_SAVE_REGS
;
2402 if (type
->type
->byref
)
2405 klass
= mono_class_from_mono_type (type
->type
);
2406 if (klass
->generic_container
) {
2407 return type
; /* check this one */
2409 if (klass
->generic_class
) {
2410 MonoClass
*generic_class
= klass
->generic_class
->container_class
;
2412 if (generic_class
->wastypebuilder
&& generic_class
->reflection_info
)
2413 return generic_class
->reflection_info
;
2415 return mono_type_get_object (mono_object_domain (type
), &generic_class
->byval_arg
);
2420 static MonoReflectionType
*
2421 ves_icall_Type_MakeGenericType (MonoReflectionType
*type
, MonoArray
*type_array
)
2423 MonoType
*geninst
, **types
;
2426 MONO_ARCH_SAVE_REGS
;
2428 count
= mono_array_length (type_array
);
2429 types
= g_new0 (MonoType
*, count
);
2431 for (i
= 0; i
< count
; i
++) {
2432 MonoReflectionType
*t
= mono_array_get (type_array
, gpointer
, i
);
2433 types
[i
] = t
->type
;
2436 geninst
= mono_reflection_bind_generic_parameters (type
, count
, types
);
2441 return mono_type_get_object (mono_object_domain (type
), geninst
);
2445 ves_icall_Type_get_IsGenericInstance (MonoReflectionType
*type
)
2448 MONO_ARCH_SAVE_REGS
;
2450 if (type
->type
->byref
)
2453 klass
= mono_class_from_mono_type (type
->type
);
2454 return klass
->generic_class
!= NULL
;
2458 ves_icall_Type_get_IsGenericType (MonoReflectionType
*type
)
2461 MONO_ARCH_SAVE_REGS
;
2463 if (!IS_MONOTYPE (type
))
2466 if (type
->type
->byref
)
2469 klass
= mono_class_from_mono_type (type
->type
);
2470 return klass
->generic_class
!= NULL
|| klass
->generic_container
!= NULL
;
2474 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType
*type
)
2476 MONO_ARCH_SAVE_REGS
;
2478 if (!IS_MONOTYPE (type
))
2481 if (is_generic_parameter (type
->type
))
2482 return mono_type_get_generic_param_num (type
->type
);
2486 static GenericParameterAttributes
2487 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType
*type
)
2489 MONO_ARCH_SAVE_REGS
;
2491 g_assert (IS_MONOTYPE (type
));
2492 g_assert (is_generic_parameter (type
->type
));
2493 return mono_generic_param_info (type
->type
->data
.generic_param
)->flags
;
2497 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType
*type
)
2499 MonoGenericParamInfo
*param_info
;
2505 MONO_ARCH_SAVE_REGS
;
2507 g_assert (IS_MONOTYPE (type
));
2509 domain
= mono_object_domain (type
);
2510 param_info
= mono_generic_param_info (type
->type
->data
.generic_param
);
2511 for (count
= 0, ptr
= param_info
->constraints
; ptr
&& *ptr
; ptr
++, count
++)
2514 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
2515 for (i
= 0; i
< count
; i
++)
2516 mono_array_setref (res
, i
, mono_type_get_object (domain
, ¶m_info
->constraints
[i
]->byval_arg
));
2523 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType
*type
)
2525 MONO_ARCH_SAVE_REGS
;
2526 return is_generic_parameter (type
->type
);
2530 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder
*tb
)
2532 MONO_ARCH_SAVE_REGS
;
2533 return is_generic_parameter (tb
->type
.type
);
2537 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType
*enumtype
,
2538 MonoReflectionType
*t
)
2540 enumtype
->type
= t
->type
;
2543 static MonoReflectionMethod
*
2544 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType
*type
,
2545 MonoReflectionMethod
* generic
)
2552 MONO_ARCH_SAVE_REGS
;
2554 domain
= ((MonoObject
*)type
)->vtable
->domain
;
2556 klass
= mono_class_from_mono_type (type
->type
);
2559 while ((method
= mono_class_get_methods (klass
, &iter
))) {
2560 if (method
->token
== generic
->method
->token
)
2561 return mono_method_get_object (domain
, method
, klass
);
2569 static MonoReflectionMethod
*
2570 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType
*ref_type
)
2573 MonoType
*type
= ref_type
->type
;
2575 MONO_ARCH_SAVE_REGS
;
2577 if (type
->byref
|| (type
->type
!= MONO_TYPE_MVAR
&& type
->type
!= MONO_TYPE_VAR
))
2578 mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2579 if (type
->type
== MONO_TYPE_VAR
)
2582 method
= mono_type_get_generic_param_owner (type
)->owner
.method
;
2584 return mono_method_get_object (mono_object_domain (ref_type
), method
, method
->klass
);
2587 static MonoReflectionDllImportAttribute
*
2588 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod
*method
)
2590 static MonoClass
*DllImportAttributeClass
= NULL
;
2591 MonoDomain
*domain
= mono_domain_get ();
2592 MonoReflectionDllImportAttribute
*attr
;
2593 MonoImage
*image
= method
->klass
->image
;
2594 MonoMethodPInvoke
*piinfo
= (MonoMethodPInvoke
*)method
;
2595 MonoTableInfo
*tables
= image
->tables
;
2596 MonoTableInfo
*im
= &tables
[MONO_TABLE_IMPLMAP
];
2597 MonoTableInfo
*mr
= &tables
[MONO_TABLE_MODULEREF
];
2598 guint32 im_cols
[MONO_IMPLMAP_SIZE
];
2599 guint32 scope_token
;
2600 const char *import
= NULL
;
2601 const char *scope
= NULL
;
2604 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
2607 if (!DllImportAttributeClass
) {
2608 DllImportAttributeClass
=
2609 mono_class_from_name (mono_defaults
.corlib
,
2610 "System.Runtime.InteropServices", "DllImportAttribute");
2611 g_assert (DllImportAttributeClass
);
2614 if (method
->klass
->image
->dynamic
) {
2615 MonoReflectionMethodAux
*method_aux
=
2616 g_hash_table_lookup (
2617 ((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
2619 import
= method_aux
->dllentry
;
2620 scope
= method_aux
->dll
;
2623 if (!import
|| !scope
) {
2624 mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2629 if (piinfo
->implmap_idx
) {
2630 mono_metadata_decode_row (im
, piinfo
->implmap_idx
- 1, im_cols
, MONO_IMPLMAP_SIZE
);
2632 piinfo
->piflags
= im_cols
[MONO_IMPLMAP_FLAGS
];
2633 import
= mono_metadata_string_heap (image
, im_cols
[MONO_IMPLMAP_NAME
]);
2634 scope_token
= mono_metadata_decode_row_col (mr
, im_cols
[MONO_IMPLMAP_SCOPE
] - 1, MONO_MODULEREF_NAME
);
2635 scope
= mono_metadata_string_heap (image
, scope_token
);
2638 flags
= piinfo
->piflags
;
2640 attr
= (MonoReflectionDllImportAttribute
*)mono_object_new (domain
, DllImportAttributeClass
);
2642 MONO_OBJECT_SETREF (attr
, dll
, mono_string_new (domain
, scope
));
2643 MONO_OBJECT_SETREF (attr
, entry_point
, mono_string_new (domain
, import
));
2644 attr
->call_conv
= (flags
& 0x700) >> 8;
2645 attr
->charset
= ((flags
& 0x6) >> 1) + 1;
2646 if (attr
->charset
== 1)
2648 attr
->exact_spelling
= (flags
& 0x1) != 0;
2649 attr
->set_last_error
= (flags
& 0x40) != 0;
2650 attr
->best_fit_mapping
= (flags
& 0x30) == 0x10;
2651 attr
->throw_on_unmappable
= (flags
& 0x3000) == 0x1000;
2652 attr
->preserve_sig
= FALSE
;
2657 static MonoReflectionMethod
*
2658 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod
*method
)
2660 MonoMethodInflated
*imethod
;
2663 MONO_ARCH_SAVE_REGS
;
2665 if (method
->method
->is_generic
)
2668 if (!method
->method
->is_inflated
)
2671 imethod
= (MonoMethodInflated
*) method
->method
;
2673 result
= imethod
->declaring
;
2674 /* Not a generic method. */
2675 if (!result
->is_generic
)
2678 if (method
->method
->klass
->image
->dynamic
) {
2679 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->method
->klass
->image
;
2680 MonoReflectionMethod
*res
;
2683 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2684 * the dynamic case as well ?
2686 mono_loader_lock ();
2687 res
= mono_g_hash_table_lookup (image
->generic_def_objects
, imethod
);
2688 mono_loader_unlock ();
2694 if (imethod
->context
.class_inst
) {
2695 MonoClass
*klass
= ((MonoMethod
*) imethod
)->klass
;
2696 /*Generic methods gets the context of the GTD.*/
2697 if (mono_class_get_context (klass
))
2698 result
= mono_class_inflate_generic_method_full (result
, klass
, mono_class_get_context (klass
));
2701 return mono_method_get_object (mono_object_domain (method
), result
, NULL
);
2705 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod
*method
)
2707 MONO_ARCH_SAVE_REGS
;
2709 return mono_method_signature (method
->method
)->generic_param_count
!= 0;
2713 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod
*method
)
2715 MONO_ARCH_SAVE_REGS
;
2717 return method
->method
->is_generic
;
2721 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod
*method
)
2726 MONO_ARCH_SAVE_REGS
;
2728 domain
= mono_object_domain (method
);
2730 if (method
->method
->is_inflated
) {
2731 MonoGenericInst
*inst
= mono_method_get_context (method
->method
)->method_inst
;
2734 count
= inst
->type_argc
;
2735 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2737 for (i
= 0; i
< count
; i
++)
2738 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2744 count
= mono_method_signature (method
->method
)->generic_param_count
;
2745 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2747 for (i
= 0; i
< count
; i
++) {
2748 MonoGenericContainer
*container
= mono_method_get_generic_container (method
->method
);
2749 MonoGenericParam
*param
= mono_generic_container_get_param (container
, i
);
2750 MonoClass
*pklass
= mono_class_from_generic_parameter (
2751 param
, method
->method
->klass
->image
, TRUE
);
2752 mono_array_setref (res
, i
,
2753 mono_type_get_object (domain
, &pklass
->byval_arg
));
2760 ves_icall_InternalInvoke (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoException
**exc
)
2763 * Invoke from reflection is supposed to always be a virtual call (the API
2764 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2765 * greater flexibility.
2767 MonoMethod
*m
= method
->method
;
2771 MONO_ARCH_SAVE_REGS
;
2775 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
)
2776 mono_security_core_clr_ensure_reflection_access_method (m
);
2778 if (!(m
->flags
& METHOD_ATTRIBUTE_STATIC
)) {
2780 if (!mono_object_isinst (this, m
->klass
)) {
2781 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Object does not match target type."));
2784 m
= mono_object_get_virtual_method (this, m
);
2785 /* must pass the pointer to the value for valuetype methods */
2786 if (m
->klass
->valuetype
)
2787 obj
= mono_object_unbox (this);
2788 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
2789 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target."));
2794 pcount
= params
? mono_array_length (params
): 0;
2795 if (pcount
!= mono_method_signature (m
)->param_count
) {
2796 mono_gc_wbarrier_generic_store (exc
, (MonoObject
*) mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException"));
2800 if ((m
->klass
->flags
& TYPE_ATTRIBUTE_ABSTRACT
) && !strcmp (m
->name
, ".ctor") && !this) {
2801 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."));
2805 if (m
->klass
->image
->assembly
->ref_only
) {
2806 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."));
2810 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
2812 mono_array_size_t
*lengths
;
2813 mono_array_size_t
*lower_bounds
;
2814 pcount
= mono_array_length (params
);
2815 lengths
= alloca (sizeof (mono_array_size_t
) * pcount
);
2816 for (i
= 0; i
< pcount
; ++i
)
2817 lengths
[i
] = *(mono_array_size_t
*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
2819 if (m
->klass
->rank
== pcount
) {
2820 /* Only lengths provided. */
2821 lower_bounds
= NULL
;
2823 g_assert (pcount
== (m
->klass
->rank
* 2));
2824 /* lower bounds are first. */
2825 lower_bounds
= lengths
;
2826 lengths
+= m
->klass
->rank
;
2829 return (MonoObject
*)mono_array_new_full (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
);
2831 return mono_runtime_invoke_array (m
, obj
, params
, NULL
);
2835 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoArray
**outArgs
)
2837 MonoDomain
*domain
= mono_object_domain (method
);
2838 MonoMethod
*m
= method
->method
;
2839 MonoMethodSignature
*sig
= mono_method_signature (m
);
2840 MonoArray
*out_args
;
2842 int i
, j
, outarg_count
= 0;
2844 MONO_ARCH_SAVE_REGS
;
2846 if (m
->klass
== mono_defaults
.object_class
) {
2848 if (!strcmp (m
->name
, "FieldGetter")) {
2849 MonoClass
*k
= this->vtable
->klass
;
2853 /* If this is a proxy, then it must be a CBO */
2854 if (k
== mono_defaults
.transparent_proxy_class
) {
2855 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2856 this = tp
->rp
->unwrapped_server
;
2858 k
= this->vtable
->klass
;
2861 name
= mono_array_get (params
, MonoString
*, 1);
2862 str
= mono_string_to_utf8 (name
);
2865 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2867 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2868 if (field_klass
->valuetype
)
2869 result
= mono_value_box (domain
, field_klass
, (char *)this + field
->offset
);
2871 result
= *((gpointer
*)((char *)this + field
->offset
));
2873 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 1);
2874 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2875 mono_array_setref (out_args
, 0, result
);
2883 g_assert_not_reached ();
2885 } else if (!strcmp (m
->name
, "FieldSetter")) {
2886 MonoClass
*k
= this->vtable
->klass
;
2892 /* If this is a proxy, then it must be a CBO */
2893 if (k
== mono_defaults
.transparent_proxy_class
) {
2894 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
2895 this = tp
->rp
->unwrapped_server
;
2897 k
= this->vtable
->klass
;
2900 name
= mono_array_get (params
, MonoString
*, 1);
2901 str
= mono_string_to_utf8 (name
);
2904 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
2906 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
2907 MonoObject
*val
= mono_array_get (params
, gpointer
, 2);
2909 if (field_klass
->valuetype
) {
2910 size
= mono_type_size (field
->type
, &align
);
2911 g_assert (size
== mono_class_value_size (field_klass
, NULL
));
2912 mono_gc_wbarrier_value_copy ((char *)this + field
->offset
, (char*)val
+ sizeof (MonoObject
), 1, field_klass
);
2914 mono_gc_wbarrier_set_field (this, (char*)this + field
->offset
, val
);
2917 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 0);
2918 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2928 g_assert_not_reached ();
2933 for (i
= 0; i
< mono_array_length (params
); i
++) {
2934 if (sig
->params
[i
]->byref
)
2938 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, outarg_count
);
2940 /* handle constructors only for objects already allocated */
2941 if (!strcmp (method
->method
->name
, ".ctor"))
2944 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2945 g_assert (!method
->method
->klass
->valuetype
);
2946 result
= mono_runtime_invoke_array (method
->method
, this, params
, NULL
);
2948 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
2949 if (sig
->params
[i
]->byref
) {
2951 arg
= mono_array_get (params
, gpointer
, i
);
2952 mono_array_setref (out_args
, j
, arg
);
2957 mono_gc_wbarrier_generic_store (outArgs
, (MonoObject
*) out_args
);
2963 read_enum_value (char *mem
, int type
)
2967 return *(guint8
*)mem
;
2969 return *(gint8
*)mem
;
2971 return *(guint16
*)mem
;
2973 return *(gint16
*)mem
;
2975 return *(guint32
*)mem
;
2977 return *(gint32
*)mem
;
2979 return *(guint64
*)mem
;
2981 return *(gint64
*)mem
;
2983 g_assert_not_reached ();
2989 write_enum_value (char *mem
, int type
, guint64 value
)
2993 case MONO_TYPE_I1
: {
2994 guint8
*p
= (guint8
*)mem
;
2999 case MONO_TYPE_I2
: {
3000 guint16
*p
= (void*)mem
;
3005 case MONO_TYPE_I4
: {
3006 guint32
*p
= (void*)mem
;
3011 case MONO_TYPE_I8
: {
3012 guint64
*p
= (void*)mem
;
3017 g_assert_not_reached ();
3023 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, MonoObject
*value
)
3026 MonoClass
*enumc
, *objc
;
3030 MONO_ARCH_SAVE_REGS
;
3032 MONO_CHECK_ARG_NULL (enumType
);
3033 MONO_CHECK_ARG_NULL (value
);
3035 domain
= mono_object_domain (enumType
);
3036 enumc
= mono_class_from_mono_type (enumType
->type
);
3037 objc
= value
->vtable
->klass
;
3039 if (!enumc
->enumtype
)
3040 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3041 if (!((objc
->enumtype
) || (objc
->byval_arg
.type
>= MONO_TYPE_I1
&& objc
->byval_arg
.type
<= MONO_TYPE_U8
)))
3042 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."));
3044 res
= mono_object_new (domain
, enumc
);
3045 val
= read_enum_value ((char *)value
+ sizeof (MonoObject
), objc
->enumtype
? mono_class_enum_basetype (objc
)->type
: objc
->byval_arg
.type
);
3046 write_enum_value ((char *)res
+ sizeof (MonoObject
), mono_class_enum_basetype (enumc
)->type
, val
);
3052 ves_icall_System_Enum_get_value (MonoObject
*this)
3060 MONO_ARCH_SAVE_REGS
;
3065 g_assert (this->vtable
->klass
->enumtype
);
3067 enumc
= mono_class_from_mono_type (mono_class_enum_basetype (this->vtable
->klass
));
3068 res
= mono_object_new (mono_object_domain (this), enumc
);
3069 dst
= (char *)res
+ sizeof (MonoObject
);
3070 src
= (char *)this + sizeof (MonoObject
);
3071 size
= mono_class_value_size (enumc
, NULL
);
3073 memcpy (dst
, src
, size
);
3078 static MonoReflectionType
*
3079 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3081 MONO_ARCH_SAVE_REGS
;
3083 return mono_type_get_object (mono_object_domain (type
), mono_class_enum_basetype (mono_class_from_mono_type (type
->type
)));
3087 ves_icall_System_Enum_compare_value_to (MonoObject
*this, MonoObject
*other
)
3089 gpointer tdata
= (char *)this + sizeof (MonoObject
);
3090 gpointer odata
= (char *)other
+ sizeof (MonoObject
);
3091 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3092 g_assert (basetype
);
3094 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3095 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3096 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3099 return me > other ? 1 : -1; \
3102 #define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
3103 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3104 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3107 return me - other; \
3110 switch (basetype
->type
) {
3112 COMPARE_ENUM_VALUES (guint8
);
3114 COMPARE_ENUM_VALUES (gint8
);
3115 case MONO_TYPE_CHAR
:
3117 COMPARE_ENUM_VALUES_RANGE (guint16
);
3119 COMPARE_ENUM_VALUES (gint16
);
3121 COMPARE_ENUM_VALUES (guint32
);
3123 COMPARE_ENUM_VALUES (gint32
);
3125 COMPARE_ENUM_VALUES (guint64
);
3127 COMPARE_ENUM_VALUES (gint64
);
3129 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3131 #undef COMPARE_ENUM_VALUES_RANGE
3132 #undef COMPARE_ENUM_VALUES
3137 ves_icall_System_Enum_get_hashcode (MonoObject
*this)
3139 gpointer data
= (char *)this + sizeof (MonoObject
);
3140 MonoType
*basetype
= mono_class_enum_basetype (this->vtable
->klass
);
3141 g_assert (basetype
);
3143 switch (basetype
->type
) {
3145 return *((gint8
*)data
);
3147 return *((guint8
*)data
);
3148 case MONO_TYPE_CHAR
:
3150 return *((guint16
*)data
);
3153 return *((gint16
*)data
);
3155 return *((guint32
*)data
);
3157 return *((gint32
*)data
);
3159 case MONO_TYPE_I8
: {
3160 gint64 value
= *((gint64
*)data
);
3161 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3164 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3170 ves_icall_get_enum_info (MonoReflectionType
*type
, MonoEnumInfo
*info
)
3172 MonoDomain
*domain
= mono_object_domain (type
);
3173 MonoClass
*enumc
= mono_class_from_mono_type (type
->type
);
3174 guint j
= 0, nvalues
, crow
;
3176 MonoClassField
*field
;
3178 MONO_ARCH_SAVE_REGS
;
3180 MONO_STRUCT_SETREF (info
, utype
, mono_type_get_object (domain
, mono_class_enum_basetype (enumc
)));
3181 nvalues
= mono_class_num_fields (enumc
) ? mono_class_num_fields (enumc
) - 1 : 0;
3182 MONO_STRUCT_SETREF (info
, names
, mono_array_new (domain
, mono_defaults
.string_class
, nvalues
));
3183 MONO_STRUCT_SETREF (info
, values
, mono_array_new (domain
, enumc
, nvalues
));
3187 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3190 MonoTypeEnum def_type
;
3192 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3194 if (mono_field_is_deleted (field
))
3196 mono_array_setref (info
->names
, j
, mono_string_new (domain
, mono_field_get_name (field
)));
3198 p
= mono_class_get_field_default_value (field
, &def_type
);
3199 len
= mono_metadata_decode_blob_size (p
, &p
);
3200 switch (mono_class_enum_basetype (enumc
)->type
) {
3203 mono_array_set (info
->values
, gchar
, j
, *p
);
3205 case MONO_TYPE_CHAR
:
3208 mono_array_set (info
->values
, gint16
, j
, read16 (p
));
3212 mono_array_set (info
->values
, gint32
, j
, read32 (p
));
3216 mono_array_set (info
->values
, gint64
, j
, read64 (p
));
3219 g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc
)->type
);
3226 BFLAGS_IgnoreCase
= 1,
3227 BFLAGS_DeclaredOnly
= 2,
3228 BFLAGS_Instance
= 4,
3230 BFLAGS_Public
= 0x10,
3231 BFLAGS_NonPublic
= 0x20,
3232 BFLAGS_FlattenHierarchy
= 0x40,
3233 BFLAGS_InvokeMethod
= 0x100,
3234 BFLAGS_CreateInstance
= 0x200,
3235 BFLAGS_GetField
= 0x400,
3236 BFLAGS_SetField
= 0x800,
3237 BFLAGS_GetProperty
= 0x1000,
3238 BFLAGS_SetProperty
= 0x2000,
3239 BFLAGS_ExactBinding
= 0x10000,
3240 BFLAGS_SuppressChangeType
= 0x20000,
3241 BFLAGS_OptionalParamBinding
= 0x40000
3244 static MonoReflectionField
*
3245 ves_icall_Type_GetField (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3248 MonoClass
*startklass
, *klass
;
3250 MonoClassField
*field
;
3253 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3254 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3255 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3257 MONO_ARCH_SAVE_REGS
;
3260 mono_raise_exception (mono_get_exception_argument_null ("name"));
3261 if (type
->type
->byref
)
3264 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? mono_utf8_strcasecmp
: strcmp
;
3267 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3268 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3271 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3274 if (field
->type
== NULL
)
3276 if (mono_field_is_deleted (field
))
3278 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3279 if (bflags
& BFLAGS_Public
)
3281 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3282 if (bflags
& BFLAGS_NonPublic
) {
3289 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3290 if (bflags
& BFLAGS_Static
)
3291 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3294 if (bflags
& BFLAGS_Instance
)
3301 utf8_name
= mono_string_to_utf8 (name
);
3303 if (compare_func (mono_field_get_name (field
), utf8_name
)) {
3309 return mono_field_get_object (domain
, klass
, field
);
3311 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3318 ves_icall_Type_GetFields_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3321 MonoClass
*startklass
, *klass
, *refklass
;
3326 MonoClassField
*field
;
3327 MonoPtrArray tmp_array
;
3329 MONO_ARCH_SAVE_REGS
;
3331 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3332 if (type
->type
->byref
)
3333 return mono_array_new (domain
, mono_defaults
.field_info_class
, 0);
3334 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3335 refklass
= mono_class_from_mono_type (reftype
->type
);
3337 mono_ptr_array_init (tmp_array
, 2);
3340 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3341 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3344 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3346 if (mono_field_is_deleted (field
))
3348 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3349 if (bflags
& BFLAGS_Public
)
3351 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3352 if (bflags
& BFLAGS_NonPublic
) {
3359 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3360 if (bflags
& BFLAGS_Static
)
3361 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3364 if (bflags
& BFLAGS_Instance
)
3370 member
= (MonoObject
*)mono_field_get_object (domain
, refklass
, field
);
3371 mono_ptr_array_append (tmp_array
, member
);
3373 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3376 res
= mono_array_new_cached (domain
, mono_defaults
.field_info_class
, mono_ptr_array_size (tmp_array
));
3378 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3379 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3381 mono_ptr_array_destroy (tmp_array
);
3387 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3389 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3390 case METHOD_ATTRIBUTE_ASSEM
:
3391 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3392 case METHOD_ATTRIBUTE_PRIVATE
:
3394 case METHOD_ATTRIBUTE_PUBLIC
:
3402 ves_icall_Type_GetMethodsByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3404 static MonoClass
*MethodInfo_array
;
3406 MonoClass
*startklass
, *klass
, *refklass
;
3411 int i
, len
, match
, nslots
;
3412 /*FIXME, use MonoBitSet*/
3413 guint32 method_slots_default
[8];
3414 guint32
*method_slots
= NULL
;
3415 gchar
*mname
= NULL
;
3416 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3417 MonoVTable
*array_vtable
;
3419 MonoPtrArray tmp_array
;
3421 MONO_ARCH_SAVE_REGS
;
3423 mono_ptr_array_init (tmp_array
, 4);
3425 if (!MethodInfo_array
) {
3426 MonoClass
*klass
= mono_array_class_get (mono_defaults
.method_info_class
, 1);
3427 mono_memory_barrier ();
3428 MethodInfo_array
= klass
;
3431 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3432 array_vtable
= mono_class_vtable_full (domain
, MethodInfo_array
, TRUE
);
3433 if (type
->type
->byref
)
3434 return mono_array_new_specific (array_vtable
, 0);
3435 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3436 refklass
= mono_class_from_mono_type (reftype
->type
);
3439 mname
= mono_string_to_utf8 (name
);
3440 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3443 /* An optimization for calls made from Delegate:CreateDelegate () */
3444 if (klass
->delegate
&& mname
&& !strcmp (mname
, "Invoke") && (bflags
== (BFLAGS_Public
| BFLAGS_Static
| BFLAGS_Instance
))) {
3445 method
= mono_get_delegate_invoke (klass
);
3446 if (mono_loader_get_last_error ())
3449 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3451 res
= mono_array_new_specific (array_vtable
, 1);
3452 mono_array_setref (res
, 0, member
);
3457 mono_class_setup_vtable (klass
);
3458 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3461 if (is_generic_parameter (type
->type
))
3462 nslots
= mono_class_get_vtable_size (klass
->parent
);
3464 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : mono_class_get_vtable_size (klass
);
3465 if (nslots
>= sizeof (method_slots_default
) * 8) {
3466 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3468 method_slots
= method_slots_default
;
3469 memset (method_slots
, 0, sizeof (method_slots_default
));
3472 mono_class_setup_vtable (klass
);
3473 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
|| mono_loader_get_last_error ())
3477 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3479 if (method
->slot
!= -1) {
3480 g_assert (method
->slot
< nslots
);
3481 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3483 if (!(method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
))
3484 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3487 if (method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3489 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3490 if (bflags
& BFLAGS_Public
)
3492 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3498 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3499 if (bflags
& BFLAGS_Static
)
3500 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3503 if (bflags
& BFLAGS_Instance
)
3511 if (compare_func (mname
, method
->name
))
3517 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3519 mono_ptr_array_append (tmp_array
, member
);
3521 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3525 if (method_slots
!= method_slots_default
)
3526 g_free (method_slots
);
3528 res
= mono_array_new_specific (array_vtable
, mono_ptr_array_size (tmp_array
));
3530 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3531 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3533 mono_ptr_array_destroy (tmp_array
);
3538 if (method_slots
!= method_slots_default
)
3539 g_free (method_slots
);
3540 mono_ptr_array_destroy (tmp_array
);
3541 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3542 ex
= mono_class_get_exception_for_failure (klass
);
3544 ex
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
3545 mono_loader_clear_error ();
3547 mono_raise_exception (ex
);
3552 ves_icall_Type_GetConstructors_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3555 static MonoClass
*System_Reflection_ConstructorInfo
;
3556 MonoClass
*startklass
, *klass
, *refklass
;
3561 gpointer iter
= NULL
;
3562 MonoPtrArray tmp_array
;
3564 MONO_ARCH_SAVE_REGS
;
3566 mono_ptr_array_init (tmp_array
, 4); /*FIXME, guestimating*/
3568 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3569 if (type
->type
->byref
)
3570 return mono_array_new_cached (domain
, mono_defaults
.method_info_class
, 0);
3571 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3572 refklass
= mono_class_from_mono_type (reftype
->type
);
3574 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3575 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3577 if (!System_Reflection_ConstructorInfo
)
3578 System_Reflection_ConstructorInfo
= mono_class_from_name (
3579 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
3582 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3584 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
3586 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3587 if (bflags
& BFLAGS_Public
)
3590 if (bflags
& BFLAGS_NonPublic
)
3596 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3597 if (bflags
& BFLAGS_Static
)
3598 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3601 if (bflags
& BFLAGS_Instance
)
3607 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3609 mono_ptr_array_append (tmp_array
, member
);
3612 res
= mono_array_new_cached (domain
, System_Reflection_ConstructorInfo
, mono_ptr_array_size (tmp_array
));
3614 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3615 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3617 mono_ptr_array_destroy (tmp_array
);
3623 property_hash (gconstpointer data
)
3625 MonoProperty
*prop
= (MonoProperty
*)data
;
3627 return g_str_hash (prop
->name
);
3631 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
3633 // Properties are hide-by-name-and-signature
3634 if (!g_str_equal (prop1
->name
, prop2
->name
))
3637 if (prop1
->get
&& prop2
->get
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->get
), mono_method_signature (prop2
->get
)))
3639 if (prop1
->set
&& prop2
->set
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->set
), mono_method_signature (prop2
->set
)))
3645 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
3650 return method_nonpublic (accessor
, start_klass
);
3654 ves_icall_Type_GetPropertiesByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3657 static MonoClass
*System_Reflection_PropertyInfo
;
3658 MonoClass
*startklass
, *klass
;
3664 gchar
*propname
= NULL
;
3665 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3667 GHashTable
*properties
;
3668 MonoPtrArray tmp_array
;
3670 MONO_ARCH_SAVE_REGS
;
3672 mono_ptr_array_init (tmp_array
, 8); /*This the average for ASP.NET types*/
3674 if (!System_Reflection_PropertyInfo
)
3675 System_Reflection_PropertyInfo
= mono_class_from_name (
3676 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
3678 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3679 if (type
->type
->byref
)
3680 return mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, 0);
3681 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3683 propname
= mono_string_to_utf8 (name
);
3684 compare_func
= (ignore_case
) ? mono_utf8_strcasecmp
: strcmp
;
3687 mono_class_setup_vtable (klass
);
3689 properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
3691 mono_class_setup_vtable (klass
);
3692 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3693 g_hash_table_destroy (properties
);
3696 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3700 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
3706 flags
= method
->flags
;
3709 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
3710 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
3711 if (bflags
& BFLAGS_Public
)
3713 } else if (bflags
& BFLAGS_NonPublic
) {
3714 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
3715 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
3722 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
3723 if (bflags
& BFLAGS_Static
)
3724 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3727 if (bflags
& BFLAGS_Instance
)
3736 if (compare_func (propname
, prop
->name
))
3740 if (g_hash_table_lookup (properties
, prop
))
3743 mono_ptr_array_append (tmp_array
, mono_property_get_object (domain
, startklass
, prop
));
3745 g_hash_table_insert (properties
, prop
, prop
);
3747 if ((!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
)))
3750 g_hash_table_destroy (properties
);
3753 res
= mono_array_new_cached (domain
, System_Reflection_PropertyInfo
, mono_ptr_array_size (tmp_array
));
3754 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3755 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3757 mono_ptr_array_destroy (tmp_array
);
3762 static MonoReflectionEvent
*
3763 ves_icall_MonoType_GetEvent (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3766 MonoClass
*klass
, *startklass
;
3772 MONO_ARCH_SAVE_REGS
;
3774 event_name
= mono_string_to_utf8 (name
);
3775 if (type
->type
->byref
)
3777 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3778 domain
= mono_object_domain (type
);
3781 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3782 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3785 while ((event
= mono_class_get_events (klass
, &iter
))) {
3786 if (strcmp (event
->name
, event_name
))
3789 method
= event
->add
;
3791 method
= event
->remove
;
3793 method
= event
->raise
;
3795 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3796 if (!(bflags
& BFLAGS_Public
))
3799 if (!(bflags
& BFLAGS_NonPublic
))
3801 if ((klass
!= startklass
) && (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PRIVATE
)
3805 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3806 if (!(bflags
& BFLAGS_Static
))
3808 if (!(bflags
& BFLAGS_FlattenHierarchy
) && (klass
!= startklass
))
3811 if (!(bflags
& BFLAGS_Instance
))
3815 if (!(bflags
& BFLAGS_NonPublic
))
3818 g_free (event_name
);
3819 return mono_event_get_object (domain
, startklass
, event
);
3822 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3825 g_free (event_name
);
3830 ves_icall_Type_GetEvents_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3833 static MonoClass
*System_Reflection_EventInfo
;
3834 MonoClass
*startklass
, *klass
;
3841 MonoPtrArray tmp_array
;
3843 MONO_ARCH_SAVE_REGS
;
3845 mono_ptr_array_init (tmp_array
, 4);
3847 if (!System_Reflection_EventInfo
)
3848 System_Reflection_EventInfo
= mono_class_from_name (
3849 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
3851 domain
= mono_object_domain (type
);
3852 if (type
->type
->byref
)
3853 return mono_array_new_cached (domain
, System_Reflection_EventInfo
, 0);
3854 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3857 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3858 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3861 while ((event
= mono_class_get_events (klass
, &iter
))) {
3863 method
= event
->add
;
3865 method
= event
->remove
;
3867 method
= event
->raise
;
3869 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3870 if (bflags
& BFLAGS_Public
)
3872 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
3873 if (bflags
& BFLAGS_NonPublic
)
3878 if (bflags
& BFLAGS_NonPublic
)
3884 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3885 if (bflags
& BFLAGS_Static
)
3886 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3889 if (bflags
& BFLAGS_Instance
)
3894 if (bflags
& BFLAGS_Instance
)
3898 mono_ptr_array_append (tmp_array
, mono_event_get_object (domain
, startklass
, event
));
3900 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3903 res
= mono_array_new_cached (domain
, System_Reflection_EventInfo
, mono_ptr_array_size (tmp_array
));
3905 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
3906 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
3908 mono_ptr_array_destroy (tmp_array
);
3913 static MonoReflectionType
*
3914 ves_icall_Type_GetNestedType (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3922 MONO_ARCH_SAVE_REGS
;
3925 mono_raise_exception (mono_get_exception_argument_null ("name"));
3927 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3928 if (type
->type
->byref
)
3930 klass
= mono_class_from_mono_type (type
->type
);
3931 str
= mono_string_to_utf8 (name
);
3934 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3935 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3938 * If a nested type is generic, return its generic type definition.
3939 * Note that this means that the return value is essentially a
3940 * nested type of the generic type definition of @klass.
3942 * A note in MSDN claims that a generic type definition can have
3943 * nested types that aren't generic. In any case, the container of that
3944 * nested type would be the generic type definition.
3946 if (klass
->generic_class
)
3947 klass
= klass
->generic_class
->container_class
;
3950 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
3952 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
3953 if (bflags
& BFLAGS_Public
)
3956 if (bflags
& BFLAGS_NonPublic
)
3961 if (strcmp (nested
->name
, str
) == 0){
3963 return mono_type_get_object (domain
, &nested
->byval_arg
);
3966 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3973 ves_icall_Type_GetNestedTypes (MonoReflectionType
*type
, guint32 bflags
)
3982 MonoPtrArray tmp_array
;
3984 MONO_ARCH_SAVE_REGS
;
3986 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3987 if (type
->type
->byref
)
3988 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
3989 klass
= mono_class_from_mono_type (type
->type
);
3990 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3991 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3994 * If a nested type is generic, return its generic type definition.
3995 * Note that this means that the return value is essentially the set
3996 * of nested types of the generic type definition of @klass.
3998 * A note in MSDN claims that a generic type definition can have
3999 * nested types that aren't generic. In any case, the container of that
4000 * nested type would be the generic type definition.
4002 if (klass
->generic_class
)
4003 klass
= klass
->generic_class
->container_class
;
4005 mono_ptr_array_init (tmp_array
, 1);
4007 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4009 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4010 if (bflags
& BFLAGS_Public
)
4013 if (bflags
& BFLAGS_NonPublic
)
4018 member
= (MonoObject
*)mono_type_get_object (domain
, &nested
->byval_arg
);
4019 mono_ptr_array_append (tmp_array
, member
);
4022 res
= mono_array_new_cached (domain
, mono_defaults
.monotype_class
, mono_ptr_array_size (tmp_array
));
4024 for (i
= 0; i
< mono_ptr_array_size (tmp_array
); ++i
)
4025 mono_array_setref (res
, i
, mono_ptr_array_get (tmp_array
, i
));
4027 mono_ptr_array_destroy (tmp_array
);
4032 static MonoReflectionType
*
4033 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly
*assembly
, MonoReflectionModule
*module
, MonoString
*name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
)
4036 MonoType
*type
= NULL
;
4037 MonoTypeNameParse info
;
4038 gboolean type_resolve
;
4040 MONO_ARCH_SAVE_REGS
;
4042 /* On MS.NET, this does not fire a TypeResolve event */
4043 type_resolve
= TRUE
;
4044 str
= mono_string_to_utf8 (name
);
4045 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4046 if (!mono_reflection_parse_type (str
, &info
)) {
4048 mono_reflection_free_type_info (&info
);
4049 if (throwOnError
) /* uhm: this is a parse error, though... */
4050 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4051 /*g_print ("failed parse\n");*/
4055 if (info
.assembly
.name
) {
4057 mono_reflection_free_type_info (&info
);
4059 /* 1.0 and 2.0 throw different exceptions */
4060 if (mono_defaults
.generic_ilist_class
)
4061 mono_raise_exception (mono_get_exception_argument (NULL
, "Type names passed to Assembly.GetType() must not specify an assembly."));
4063 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4068 if (module
!= NULL
) {
4070 type
= mono_reflection_get_type (module
->image
, &info
, ignoreCase
, &type_resolve
);
4075 if (assembly
->assembly
->dynamic
) {
4076 /* Enumerate all modules */
4077 MonoReflectionAssemblyBuilder
*abuilder
= (MonoReflectionAssemblyBuilder
*)assembly
;
4081 if (abuilder
->modules
) {
4082 for (i
= 0; i
< mono_array_length (abuilder
->modules
); ++i
) {
4083 MonoReflectionModuleBuilder
*mb
= mono_array_get (abuilder
->modules
, MonoReflectionModuleBuilder
*, i
);
4084 type
= mono_reflection_get_type (&mb
->dynamic_image
->image
, &info
, ignoreCase
, &type_resolve
);
4090 if (!type
&& abuilder
->loaded_modules
) {
4091 for (i
= 0; i
< mono_array_length (abuilder
->loaded_modules
); ++i
) {
4092 MonoReflectionModule
*mod
= mono_array_get (abuilder
->loaded_modules
, MonoReflectionModule
*, i
);
4093 type
= mono_reflection_get_type (mod
->image
, &info
, ignoreCase
, &type_resolve
);
4100 type
= mono_reflection_get_type (assembly
->assembly
->image
, &info
, ignoreCase
, &type_resolve
);
4102 mono_reflection_free_type_info (&info
);
4104 MonoException
*e
= NULL
;
4107 e
= mono_get_exception_type_load (name
, NULL
);
4109 if (mono_loader_get_last_error () && mono_defaults
.generic_ilist_class
)
4110 e
= mono_loader_error_prepare_exception (mono_loader_get_last_error ());
4112 mono_loader_clear_error ();
4115 mono_raise_exception (e
);
4120 if (type
->type
== MONO_TYPE_CLASS
) {
4121 MonoClass
*klass
= mono_type_get_class (type
);
4123 if (mono_is_security_manager_active () && !klass
->exception_type
)
4124 /* Some security problems are detected during generic vtable construction */
4125 mono_class_setup_vtable (klass
);
4126 /* need to report exceptions ? */
4127 if (throwOnError
&& klass
->exception_type
) {
4128 /* report SecurityException (or others) that occured when loading the assembly */
4129 MonoException
*exc
= mono_class_get_exception_for_failure (klass
);
4130 mono_loader_clear_error ();
4131 mono_raise_exception (exc
);
4132 } else if (klass
->exception_type
== MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND
) {
4137 /* g_print ("got it\n"); */
4138 return mono_type_get_object (mono_object_domain (assembly
), type
);
4142 replace_shadow_path (MonoDomain
*domain
, gchar
*dirname
, gchar
**filename
)
4145 gchar
*shadow_ini_file
;
4148 /* Check for shadow-copied assembly */
4149 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4150 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4152 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4153 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4159 g_free (shadow_ini_file
);
4160 if (content
!= NULL
) {
4163 *filename
= content
;
4171 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly
*assembly
, MonoBoolean escaped
)
4173 MonoDomain
*domain
= mono_object_domain (assembly
);
4174 MonoAssembly
*mass
= assembly
->assembly
;
4175 MonoString
*res
= NULL
;
4180 MONO_ARCH_SAVE_REGS
;
4182 if (g_path_is_absolute (mass
->image
->name
)) {
4183 absolute
= g_strdup (mass
->image
->name
);
4184 dirname
= g_path_get_dirname (absolute
);
4186 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4187 dirname
= g_strdup (mass
->basedir
);
4190 replace_shadow_path (domain
, dirname
, &absolute
);
4195 for (i
= strlen (absolute
) - 1; i
>= 0; i
--)
4196 if (absolute
[i
] == '\\')
4201 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4203 const char *prepend
= "file://";
4205 if (*absolute
== '/' && *(absolute
+ 1) == '/') {
4208 prepend
= "file:///";
4211 uri
= g_strconcat (prepend
, absolute
, NULL
);
4215 res
= mono_string_new (domain
, uri
);
4223 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly
*assembly
)
4225 MonoAssembly
*mass
= assembly
->assembly
;
4227 MONO_ARCH_SAVE_REGS
;
4229 return mass
->in_gac
;
4232 static MonoReflectionAssembly
*
4233 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString
*mname
, MonoObject
*evidence
)
4237 MonoImageOpenStatus status
;
4239 MONO_ARCH_SAVE_REGS
;
4241 name
= mono_string_to_utf8 (mname
);
4242 res
= mono_assembly_load_with_partial_name (name
, &status
);
4248 return mono_assembly_get_object (mono_domain_get (), res
);
4252 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly
*assembly
)
4254 MonoDomain
*domain
= mono_object_domain (assembly
);
4257 MONO_ARCH_SAVE_REGS
;
4259 res
= mono_string_new (domain
, mono_image_get_filename (assembly
->assembly
->image
));
4265 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
*assembly
)
4267 MONO_ARCH_SAVE_REGS
;
4269 return assembly
->assembly
->ref_only
;
4273 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly
*assembly
)
4275 MonoDomain
*domain
= mono_object_domain (assembly
);
4277 MONO_ARCH_SAVE_REGS
;
4279 return mono_string_new (domain
, assembly
->assembly
->image
->version
);
4282 static MonoReflectionMethod
*
4283 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly
*assembly
)
4285 guint32 token
= mono_image_get_entry_point (assembly
->assembly
->image
);
4287 MONO_ARCH_SAVE_REGS
;
4291 return mono_method_get_object (mono_object_domain (assembly
), mono_get_method (assembly
->assembly
->image
, token
, NULL
), NULL
);
4294 static MonoReflectionModule
*
4295 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly
*assembly
)
4297 return mono_module_get_object (mono_object_domain (assembly
), assembly
->assembly
->image
);
4301 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly
*assembly
)
4303 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4304 MonoArray
*result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, table
->rows
);
4308 MONO_ARCH_SAVE_REGS
;
4310 for (i
= 0; i
< table
->rows
; ++i
) {
4311 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4312 mono_array_setref (result
, i
, mono_string_new (mono_object_domain (assembly
), val
));
4318 create_version (MonoDomain
*domain
, guint32 major
, guint32 minor
, guint32 build
, guint32 revision
)
4320 static MonoClass
*System_Version
= NULL
;
4321 static MonoMethod
*create_version
= NULL
;
4325 if (!System_Version
) {
4326 System_Version
= mono_class_from_name (mono_defaults
.corlib
, "System", "Version");
4327 g_assert (System_Version
);
4330 if (!create_version
) {
4331 MonoMethodDesc
*desc
= mono_method_desc_new (":.ctor(int,int,int,int)", FALSE
);
4332 create_version
= mono_method_desc_search_in_class (desc
, System_Version
);
4333 g_assert (create_version
);
4334 mono_method_desc_free (desc
);
4340 args
[3] = &revision
;
4341 result
= mono_object_new (domain
, System_Version
);
4342 mono_runtime_invoke (create_version
, result
, args
, NULL
);
4348 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly
*assembly
)
4350 static MonoClass
*System_Reflection_AssemblyName
;
4352 MonoDomain
*domain
= mono_object_domain (assembly
);
4354 static MonoMethod
*create_culture
= NULL
;
4355 MonoImage
*image
= assembly
->assembly
->image
;
4358 MONO_ARCH_SAVE_REGS
;
4360 if (!System_Reflection_AssemblyName
)
4361 System_Reflection_AssemblyName
= mono_class_from_name (
4362 mono_defaults
.corlib
, "System.Reflection", "AssemblyName");
4364 t
= &assembly
->assembly
->image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4367 result
= mono_array_new (domain
, System_Reflection_AssemblyName
, count
);
4369 if (count
> 0 && !create_culture
) {
4370 MonoMethodDesc
*desc
= mono_method_desc_new (
4371 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4372 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4373 g_assert (create_culture
);
4374 mono_method_desc_free (desc
);
4377 for (i
= 0; i
< count
; i
++) {
4378 MonoReflectionAssemblyName
*aname
;
4379 guint32 cols
[MONO_ASSEMBLYREF_SIZE
];
4381 mono_metadata_decode_row (t
, i
, cols
, MONO_ASSEMBLYREF_SIZE
);
4383 aname
= (MonoReflectionAssemblyName
*) mono_object_new (
4384 domain
, System_Reflection_AssemblyName
);
4386 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_NAME
])));
4388 aname
->major
= cols
[MONO_ASSEMBLYREF_MAJOR_VERSION
];
4389 aname
->minor
= cols
[MONO_ASSEMBLYREF_MINOR_VERSION
];
4390 aname
->build
= cols
[MONO_ASSEMBLYREF_BUILD_NUMBER
];
4391 aname
->revision
= cols
[MONO_ASSEMBLYREF_REV_NUMBER
];
4392 aname
->flags
= cols
[MONO_ASSEMBLYREF_FLAGS
];
4393 aname
->versioncompat
= 1; /* SameMachine (default) */
4394 aname
->hashalg
= ASSEMBLY_HASH_SHA1
; /* SHA1 (default) */
4395 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, aname
->major
, aname
->minor
, aname
->build
, aname
->revision
));
4397 if (create_culture
) {
4399 MonoBoolean assembly_ref
= 1;
4400 args
[0] = mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_CULTURE
]));
4401 args
[1] = &assembly_ref
;
4402 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4405 if (cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]) {
4406 const gchar
*pkey_ptr
= mono_metadata_blob_heap (image
, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]);
4407 guint32 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4409 if ((cols
[MONO_ASSEMBLYREF_FLAGS
] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
)) {
4410 /* public key token isn't copied - the class library will
4411 automatically generate it from the public key if required */
4412 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4413 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4415 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4416 memcpy (mono_array_addr (aname
->keyToken
, guint8
, 0), pkey_ptr
, pkey_len
);
4419 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4422 /* note: this function doesn't return the codebase on purpose (i.e. it can
4423 be used under partial trust as path information isn't present). */
4425 mono_array_setref (result
, i
, aname
);
4436 foreach_namespace (const char* key
, gconstpointer val
, NameSpaceInfo
*info
)
4438 MonoString
*name
= mono_string_new (mono_object_domain (info
->res
), key
);
4440 mono_array_setref (info
->res
, info
->idx
, name
);
4445 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly
*assembly
)
4447 MonoImage
*img
= assembly
->assembly
->image
;
4452 MONO_ARCH_SAVE_REGS
;
4454 mono_image_lock (img
);
4455 mono_image_init_name_cache (img
);
4458 len
= g_hash_table_size (img
->name_cache
);
4459 mono_image_unlock (img
);
4461 /*we can't create objects holding the image lock */
4462 res
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, len
);
4464 mono_image_lock (img
);
4465 /*len might have changed, create a new array*/
4466 if (len
!= g_hash_table_size (img
->name_cache
))
4471 g_hash_table_foreach (img
->name_cache
, (GHFunc
)foreach_namespace
, &info
);
4472 mono_image_unlock (img
);
4477 /* move this in some file in mono/util/ */
4479 g_concat_dir_and_file (const char *dir
, const char *file
)
4481 g_return_val_if_fail (dir
!= NULL
, NULL
);
4482 g_return_val_if_fail (file
!= NULL
, NULL
);
4485 * If the directory name doesn't have a / on the end, we need
4486 * to add one so we get a proper path to the file
4488 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4489 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4491 return g_strconcat (dir
, file
, NULL
);
4495 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, gint32
*size
, MonoReflectionModule
**ref_module
)
4497 char *n
= mono_string_to_utf8 (name
);
4498 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4500 guint32 cols
[MONO_MANIFEST_SIZE
];
4501 guint32 impl
, file_idx
;
4505 MONO_ARCH_SAVE_REGS
;
4507 for (i
= 0; i
< table
->rows
; ++i
) {
4508 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4509 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4510 if (strcmp (val
, n
) == 0)
4514 if (i
== table
->rows
)
4517 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4520 * this code should only be called after obtaining the
4521 * ResourceInfo and handling the other cases.
4523 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4524 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4526 module
= mono_image_load_file_for_image (assembly
->assembly
->image
, file_idx
);
4531 module
= assembly
->assembly
->image
;
4533 mono_gc_wbarrier_generic_store (ref_module
, (MonoObject
*) mono_module_get_object (mono_domain_get (), module
));
4535 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4539 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoManifestResourceInfo
*info
)
4541 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4543 guint32 cols
[MONO_MANIFEST_SIZE
];
4544 guint32 file_cols
[MONO_FILE_SIZE
];
4548 MONO_ARCH_SAVE_REGS
;
4550 n
= mono_string_to_utf8 (name
);
4551 for (i
= 0; i
< table
->rows
; ++i
) {
4552 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4553 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4554 if (strcmp (val
, n
) == 0)
4558 if (i
== table
->rows
)
4561 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4562 info
->location
= RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
;
4565 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4566 case MONO_IMPLEMENTATION_FILE
:
4567 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4568 table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4569 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4570 val
= mono_metadata_string_heap (assembly
->assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4571 MONO_OBJECT_SETREF (info
, filename
, mono_string_new (mono_object_domain (assembly
), val
));
4572 if (file_cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4575 info
->location
= RESOURCE_LOCATION_EMBEDDED
;
4578 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4579 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4580 mono_assembly_load_reference (assembly
->assembly
->image
, i
- 1);
4581 if (assembly
->assembly
->image
->references
[i
- 1] == (gpointer
)-1) {
4582 char *msg
= g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->assembly
->image
->name
);
4583 MonoException
*ex
= mono_get_exception_file_not_found2 (msg
, NULL
);
4585 mono_raise_exception (ex
);
4587 MONO_OBJECT_SETREF (info
, assembly
, mono_assembly_get_object (mono_domain_get (), assembly
->assembly
->image
->references
[i
- 1]));
4589 /* Obtain info recursively */
4590 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info
->assembly
, name
, info
);
4591 info
->location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4594 case MONO_IMPLEMENTATION_EXP_TYPE
:
4595 g_assert_not_reached ();
4604 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoBoolean resource_modules
)
4606 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4607 MonoArray
*result
= NULL
;
4612 MONO_ARCH_SAVE_REGS
;
4614 /* check hash if needed */
4616 n
= mono_string_to_utf8 (name
);
4617 for (i
= 0; i
< table
->rows
; ++i
) {
4618 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4619 if (strcmp (val
, n
) == 0) {
4622 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4623 fn
= mono_string_new (mono_object_domain (assembly
), n
);
4625 return (MonoObject
*)fn
;
4633 for (i
= 0; i
< table
->rows
; ++i
) {
4634 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
4638 result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, count
);
4641 for (i
= 0; i
< table
->rows
; ++i
) {
4642 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
4643 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4644 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4645 mono_array_setref (result
, count
, mono_string_new (mono_object_domain (assembly
), n
));
4650 return (MonoObject
*)result
;
4654 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
*assembly
)
4656 MonoDomain
*domain
= mono_domain_get();
4659 int i
, j
, file_count
= 0;
4660 MonoImage
**modules
;
4661 guint32 module_count
, real_module_count
;
4662 MonoTableInfo
*table
;
4663 guint32 cols
[MONO_FILE_SIZE
];
4664 MonoImage
*image
= assembly
->assembly
->image
;
4666 g_assert (image
!= NULL
);
4667 g_assert (!assembly
->assembly
->dynamic
);
4669 table
= &image
->tables
[MONO_TABLE_FILE
];
4670 file_count
= table
->rows
;
4672 modules
= image
->modules
;
4673 module_count
= image
->module_count
;
4675 real_module_count
= 0;
4676 for (i
= 0; i
< module_count
; ++i
)
4678 real_module_count
++;
4680 klass
= mono_class_from_name (mono_defaults
.corlib
, "System.Reflection", "Module");
4681 res
= mono_array_new (domain
, klass
, 1 + real_module_count
+ file_count
);
4683 mono_array_setref (res
, 0, mono_module_get_object (domain
, image
));
4685 for (i
= 0; i
< module_count
; ++i
)
4687 mono_array_setref (res
, j
, mono_module_get_object (domain
, modules
[i
]));
4691 for (i
= 0; i
< file_count
; ++i
, ++j
) {
4692 mono_metadata_decode_row (table
, i
, cols
, MONO_FILE_SIZE
);
4693 if (cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4694 mono_array_setref (res
, j
, mono_module_file_get_object (domain
, image
, i
));
4696 MonoImage
*m
= mono_image_load_file_for_image (image
, i
+ 1);
4698 MonoString
*fname
= mono_string_new (mono_domain_get (), mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]));
4699 mono_raise_exception (mono_get_exception_file_not_found2 (NULL
, fname
));
4701 mono_array_setref (res
, j
, mono_module_get_object (domain
, m
));
4708 static MonoReflectionMethod
*
4709 ves_icall_GetCurrentMethod (void)
4711 MonoMethod
*m
= mono_method_get_last_managed ();
4713 while (m
->is_inflated
)
4714 m
= ((MonoMethodInflated
*)m
)->declaring
;
4716 return mono_method_get_object (mono_domain_get (), m
, NULL
);
4721 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
4724 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
4725 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
4726 //method is inflated, we should inflate it on the other class
4727 MonoGenericContext ctx
;
4728 ctx
.method_inst
= inflated
->context
.method_inst
;
4729 ctx
.class_inst
= inflated
->context
.class_inst
;
4730 if (klass
->generic_class
)
4731 ctx
.class_inst
= klass
->generic_class
->context
.class_inst
;
4732 else if (klass
->generic_container
)
4733 ctx
.class_inst
= klass
->generic_container
->context
.class_inst
;
4734 return mono_class_inflate_generic_method_full (inflated
->declaring
, klass
, &ctx
);
4737 mono_class_setup_methods (method
->klass
);
4738 if (method
->klass
->exception_type
)
4740 for (i
= 0; i
< method
->klass
->method
.count
; ++i
) {
4741 if (method
->klass
->methods
[i
] == method
) {
4746 mono_class_setup_methods (klass
);
4747 if (klass
->exception_type
)
4749 g_assert (offset
>= 0 && offset
< klass
->method
.count
);
4750 return klass
->methods
[offset
];
4753 static MonoReflectionMethod
*
4754 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod
*method
, MonoType
*type
)
4758 klass
= mono_class_from_mono_type (type
);
4759 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
4761 if (method
->klass
!= klass
) {
4762 method
= mono_method_get_equivalent_method (method
, klass
);
4767 klass
= method
->klass
;
4768 return mono_method_get_object (mono_domain_get (), method
, klass
);
4771 static MonoReflectionMethod
*
4772 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod
*method
)
4774 return mono_method_get_object (mono_domain_get (), method
, NULL
);
4777 static MonoReflectionMethodBody
*
4778 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
)
4780 return mono_method_body_get_object (mono_domain_get (), method
);
4783 static MonoReflectionAssembly
*
4784 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4786 MonoMethod
*dest
= NULL
;
4788 MONO_ARCH_SAVE_REGS
;
4790 mono_stack_walk_no_il (get_executing
, &dest
);
4791 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4795 static MonoReflectionAssembly
*
4796 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4798 MonoDomain
* domain
= mono_domain_get ();
4800 MONO_ARCH_SAVE_REGS
;
4802 if (!domain
->entry_assembly
)
4805 return mono_assembly_get_object (domain
, domain
->entry_assembly
);
4808 static MonoReflectionAssembly
*
4809 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4814 MONO_ARCH_SAVE_REGS
;
4817 mono_stack_walk_no_il (get_executing
, &dest
);
4819 mono_stack_walk_no_il (get_caller
, &dest
);
4822 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4826 ves_icall_System_MonoType_getFullName (MonoReflectionType
*object
, gboolean full_name
,
4827 gboolean assembly_qualified
)
4829 MonoDomain
*domain
= mono_object_domain (object
);
4830 MonoTypeNameFormat format
;
4834 MONO_ARCH_SAVE_REGS
;
4836 format
= assembly_qualified
?
4837 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
4838 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
4840 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
4842 name
= mono_type_get_name_full (object
->type
, format
);
4846 if (full_name
&& (object
->type
->type
== MONO_TYPE_VAR
|| object
->type
->type
== MONO_TYPE_MVAR
)) {
4851 res
= mono_string_new (domain
, name
);
4858 fill_reflection_assembly_name (MonoDomain
*domain
, MonoReflectionAssemblyName
*aname
, MonoAssemblyName
*name
, const char *absolute
, gboolean by_default_version
, gboolean default_publickey
, gboolean default_token
)
4860 static MonoMethod
*create_culture
= NULL
;
4863 const char *pkey_ptr
;
4865 MonoBoolean assembly_ref
= 0;
4867 MONO_ARCH_SAVE_REGS
;
4869 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, name
->name
));
4870 aname
->major
= name
->major
;
4871 aname
->minor
= name
->minor
;
4872 aname
->build
= name
->build
;
4873 aname
->flags
= name
->flags
;
4874 aname
->revision
= name
->revision
;
4875 aname
->hashalg
= name
->hash_alg
;
4876 aname
->versioncompat
= 1; /* SameMachine (default) */
4878 if (by_default_version
)
4879 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, name
->major
, name
->minor
, name
->build
, name
->revision
));
4882 if (absolute
!= NULL
&& *absolute
!= '\0') {
4883 const gchar
*prepend
= "file://";
4886 codebase
= g_strdup (absolute
);
4891 for (i
= strlen (codebase
) - 1; i
>= 0; i
--)
4892 if (codebase
[i
] == '\\')
4895 if (*codebase
== '/' && *(codebase
+ 1) == '/') {
4898 prepend
= "file:///";
4902 result
= g_strconcat (prepend
, codebase
, NULL
);
4908 MONO_OBJECT_SETREF (aname
, codebase
, mono_string_new (domain
, codebase
));
4912 if (!create_culture
) {
4913 MonoMethodDesc
*desc
= mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4914 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4915 g_assert (create_culture
);
4916 mono_method_desc_free (desc
);
4919 if (name
->culture
) {
4920 args
[0] = mono_string_new (domain
, name
->culture
);
4921 args
[1] = &assembly_ref
;
4922 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4925 if (name
->public_key
) {
4926 pkey_ptr
= (char*)name
->public_key
;
4927 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4929 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4930 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4931 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4932 } else if (default_publickey
) {
4933 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4934 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
4937 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4938 if (name
->public_key_token
[0]) {
4942 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 8));
4943 p
= mono_array_addr (aname
->keyToken
, char, 0);
4945 for (i
= 0, j
= 0; i
< 8; i
++) {
4946 *p
= g_ascii_xdigit_value (name
->public_key_token
[j
++]) << 4;
4947 *p
|= g_ascii_xdigit_value (name
->public_key_token
[j
++]);
4950 } else if (default_token
) {
4951 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4956 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly
*assembly
)
4958 MonoDomain
*domain
= mono_object_domain (assembly
);
4959 MonoAssembly
*mass
= assembly
->assembly
;
4963 name
= g_strdup_printf (
4964 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4966 mass
->aname
.major
, mass
->aname
.minor
, mass
->aname
.build
, mass
->aname
.revision
,
4967 mass
->aname
.culture
&& *mass
->aname
.culture
? mass
->aname
.culture
: "neutral",
4968 mass
->aname
.public_key_token
[0] ? (char *)mass
->aname
.public_key_token
: "null",
4969 (mass
->aname
.flags
& ASSEMBLYREF_RETARGETABLE_FLAG
) ? ", Retargetable=Yes" : "");
4971 res
= mono_string_new (domain
, name
);
4978 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly
*assembly
, MonoReflectionAssemblyName
*aname
)
4981 MonoAssembly
*mass
= assembly
->assembly
;
4983 MONO_ARCH_SAVE_REGS
;
4985 if (g_path_is_absolute (mass
->image
->name
)) {
4986 fill_reflection_assembly_name (mono_object_domain (assembly
),
4987 aname
, &mass
->aname
, mass
->image
->name
, TRUE
,
4988 TRUE
, mono_framework_version () >= 2);
4991 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4993 fill_reflection_assembly_name (mono_object_domain (assembly
),
4994 aname
, &mass
->aname
, absolute
, TRUE
, TRUE
,
4995 mono_framework_version () >= 2);
5001 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString
*fname
, MonoReflectionAssemblyName
*aname
)
5004 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
5007 MonoAssemblyName name
;
5010 MONO_ARCH_SAVE_REGS
;
5012 filename
= mono_string_to_utf8 (fname
);
5014 dirname
= g_path_get_dirname (filename
);
5015 replace_shadow_path (mono_domain_get (), dirname
, &filename
);
5018 image
= mono_image_open (filename
, &status
);
5024 if (status
== MONO_IMAGE_IMAGE_INVALID
)
5025 exc
= mono_get_exception_bad_image_format2 (NULL
, fname
);
5027 exc
= mono_get_exception_file_not_found2 (NULL
, fname
);
5028 mono_raise_exception (exc
);
5031 res
= mono_assembly_fill_assembly_name (image
, &name
);
5033 mono_image_close (image
);
5035 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5038 fill_reflection_assembly_name (mono_domain_get (), aname
, &name
, filename
,
5039 TRUE
, mono_framework_version () == 1,
5040 mono_framework_version () >= 2);
5043 mono_image_close (image
);
5047 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly
*assembly
,
5048 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
)
5050 MonoBoolean result
= FALSE
;
5051 MonoDeclSecurityEntry entry
;
5053 /* SecurityAction.RequestMinimum */
5054 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5055 *minimum
= entry
.blob
;
5056 *minLength
= entry
.size
;
5059 /* SecurityAction.RequestOptional */
5060 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5061 *optional
= entry
.blob
;
5062 *optLength
= entry
.size
;
5065 /* SecurityAction.RequestRefuse */
5066 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5067 *refused
= entry
.blob
;
5068 *refLength
= entry
.size
;
5076 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArray
**exceptions
, MonoBoolean exportedOnly
)
5080 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5082 guint32 attrs
, visibility
;
5084 /* we start the count from 1 because we skip the special type <Module> */
5087 for (i
= 1; i
< tdef
->rows
; ++i
) {
5088 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5089 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5090 if (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5094 count
= tdef
->rows
- 1;
5096 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
5097 *exceptions
= mono_array_new (domain
, mono_defaults
.exception_class
, count
);
5099 for (i
= 1; i
< tdef
->rows
; ++i
) {
5100 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5101 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5102 if (!exportedOnly
|| (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)) {
5103 klass
= mono_class_get (image
, (i
+ 1) | MONO_TOKEN_TYPE_DEF
);
5105 mono_array_setref (res
, count
, mono_type_get_object (domain
, &klass
->byval_arg
));
5107 MonoLoaderError
*error
;
5110 error
= mono_loader_get_last_error ();
5111 g_assert (error
!= NULL
);
5113 ex
= mono_loader_error_prepare_exception (error
);
5114 mono_array_setref (*exceptions
, count
, ex
);
5116 if (mono_loader_get_last_error ())
5117 mono_loader_clear_error ();
5126 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly
*assembly
, MonoBoolean exportedOnly
)
5128 MonoArray
*res
= NULL
;
5129 MonoArray
*exceptions
= NULL
;
5130 MonoImage
*image
= NULL
;
5131 MonoTableInfo
*table
= NULL
;
5134 int i
, len
, ex_count
;
5136 MONO_ARCH_SAVE_REGS
;
5138 domain
= mono_object_domain (assembly
);
5140 g_assert (!assembly
->assembly
->dynamic
);
5141 image
= assembly
->assembly
->image
;
5142 table
= &image
->tables
[MONO_TABLE_FILE
];
5143 res
= mono_module_get_types (domain
, image
, &exceptions
, exportedOnly
);
5145 /* Append data from all modules in the assembly */
5146 for (i
= 0; i
< table
->rows
; ++i
) {
5147 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5148 MonoImage
*loaded_image
= mono_assembly_load_module (image
->assembly
, i
+ 1);
5151 MonoArray
*res2
= mono_module_get_types (domain
, loaded_image
, &ex2
, exportedOnly
);
5152 /* Append the new types to the end of the array */
5153 if (mono_array_length (res2
) > 0) {
5155 MonoArray
*res3
, *ex3
;
5157 len1
= mono_array_length (res
);
5158 len2
= mono_array_length (res2
);
5160 res3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5161 mono_array_memcpy_refs (res3
, 0, res
, 0, len1
);
5162 mono_array_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5165 ex3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5166 mono_array_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5167 mono_array_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5174 /* the ReflectionTypeLoadException must have all the types (Types property),
5175 * NULL replacing types which throws an exception. The LoaderException must
5176 * contain all exceptions for NULL items.
5179 len
= mono_array_length (res
);
5182 for (i
= 0; i
< len
; i
++) {
5183 MonoReflectionType
*t
= mono_array_get (res
, gpointer
, i
);
5187 klass
= mono_type_get_class (t
->type
);
5188 if ((klass
!= NULL
) && klass
->exception_type
) {
5189 /* keep the class in the list */
5190 list
= g_list_append (list
, klass
);
5191 /* and replace Type with NULL */
5192 mono_array_setref (res
, i
, NULL
);
5199 if (list
|| ex_count
) {
5201 MonoException
*exc
= NULL
;
5202 MonoArray
*exl
= NULL
;
5203 int j
, length
= g_list_length (list
) + ex_count
;
5205 mono_loader_clear_error ();
5207 exl
= mono_array_new (domain
, mono_defaults
.exception_class
, length
);
5208 /* Types for which mono_class_get () succeeded */
5209 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5210 MonoException
*exc
= mono_class_get_exception_for_failure (tmp
->data
);
5211 mono_array_setref (exl
, i
, exc
);
5213 /* Types for which it don't */
5214 for (j
= 0; j
< mono_array_length (exceptions
); ++j
) {
5215 MonoException
*exc
= mono_array_get (exceptions
, MonoException
*, j
);
5217 g_assert (i
< length
);
5218 mono_array_setref (exl
, i
, exc
);
5225 exc
= mono_get_exception_reflection_type_load (res
, exl
);
5226 mono_loader_clear_error ();
5227 mono_raise_exception (exc
);
5234 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName
*name
, MonoString
*assname
)
5236 MonoAssemblyName aname
;
5237 MonoDomain
*domain
= mono_object_domain (name
);
5239 gboolean is_version_defined
;
5240 gboolean is_token_defined
;
5242 aname
.public_key
= NULL
;
5243 val
= mono_string_to_utf8 (assname
);
5244 if (!mono_assembly_name_parse_full (val
, &aname
, TRUE
, &is_version_defined
, &is_token_defined
)) {
5245 g_free ((guint8
*) aname
.public_key
);
5250 fill_reflection_assembly_name (domain
, name
, &aname
, "", is_version_defined
,
5251 FALSE
, is_token_defined
);
5253 mono_assembly_name_free (&aname
);
5254 g_free ((guint8
*) aname
.public_key
);
5260 static MonoReflectionType
*
5261 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule
*module
)
5263 MonoDomain
*domain
= mono_object_domain (module
);
5266 MONO_ARCH_SAVE_REGS
;
5268 g_assert (module
->image
);
5270 if (module
->image
->dynamic
&& ((MonoDynamicImage
*)(module
->image
))->initial_image
)
5271 /* These images do not have a global type */
5274 klass
= mono_class_get (module
->image
, 1 | MONO_TOKEN_TYPE_DEF
);
5275 return mono_type_get_object (domain
, &klass
->byval_arg
);
5279 ves_icall_System_Reflection_Module_Close (MonoReflectionModule
*module
)
5281 /*if (module->image)
5282 mono_image_close (module->image);*/
5286 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule
*module
)
5288 MonoDomain
*domain
= mono_object_domain (module
);
5290 MONO_ARCH_SAVE_REGS
;
5292 g_assert (module
->image
);
5293 return mono_string_new (domain
, module
->image
->guid
);
5297 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule
*module
)
5300 if (module
->image
&& module
->image
->is_module_handle
)
5301 return module
->image
->raw_data
;
5304 return (gpointer
) (-1);
5308 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
)
5310 if (image
->dynamic
) {
5311 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5312 *pe_kind
= dyn
->pe_kind
;
5313 *machine
= dyn
->machine
;
5316 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5317 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5322 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
)
5324 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5328 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule
*module
)
5330 MonoArray
*exceptions
;
5333 MONO_ARCH_SAVE_REGS
;
5336 return mono_array_new (mono_object_domain (module
), mono_defaults
.monotype_class
, 0);
5338 MonoArray
*res
= mono_module_get_types (mono_object_domain (module
), module
->image
, &exceptions
, FALSE
);
5339 for (i
= 0; i
< mono_array_length (exceptions
); ++i
) {
5340 MonoException
*ex
= mono_array_get (exceptions
, MonoException
*, i
);
5342 mono_raise_exception (ex
);
5349 mono_metadata_memberref_is_method (MonoImage
*image
, guint32 token
)
5351 guint32 cols
[MONO_MEMBERREF_SIZE
];
5353 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5354 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5355 mono_metadata_decode_blob_size (sig
, &sig
);
5356 return (*sig
!= 0x6);
5360 init_generic_context_from_args (MonoGenericContext
*context
, MonoArray
*type_args
, MonoArray
*method_args
)
5363 context
->class_inst
= mono_metadata_get_generic_inst (mono_array_length (type_args
),
5364 mono_array_addr (type_args
, MonoType
*, 0));
5366 context
->class_inst
= NULL
;
5368 context
->method_inst
= mono_metadata_get_generic_inst (mono_array_length (method_args
),
5369 mono_array_addr (method_args
, MonoType
*, 0));
5371 context
->method_inst
= NULL
;
5375 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5378 int table
= mono_metadata_token_table (token
);
5379 int index
= mono_metadata_token_index (token
);
5380 MonoGenericContext context
;
5382 *error
= ResolveTokenError_Other
;
5384 /* Validate token */
5385 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5386 (table
!= MONO_TABLE_TYPESPEC
)) {
5387 *error
= ResolveTokenError_BadTable
;
5391 if (image
->dynamic
) {
5392 if (type_args
|| method_args
)
5393 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5394 klass
= mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5397 return &klass
->byval_arg
;
5400 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5401 *error
= ResolveTokenError_OutOfRange
;
5405 init_generic_context_from_args (&context
, type_args
, method_args
);
5406 klass
= mono_class_get_full (image
, token
, &context
);
5408 if (mono_loader_get_last_error ())
5409 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5412 return &klass
->byval_arg
;
5418 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5420 int table
= mono_metadata_token_table (token
);
5421 int index
= mono_metadata_token_index (token
);
5422 MonoGenericContext context
;
5425 *error
= ResolveTokenError_Other
;
5427 /* Validate token */
5428 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5429 (table
!= MONO_TABLE_MEMBERREF
)) {
5430 *error
= ResolveTokenError_BadTable
;
5434 if (image
->dynamic
) {
5435 if (type_args
|| method_args
)
5436 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5437 /* FIXME: validate memberref token type */
5438 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5441 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5442 *error
= ResolveTokenError_OutOfRange
;
5445 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_metadata_memberref_is_method (image
, token
))) {
5446 *error
= ResolveTokenError_BadTable
;
5450 init_generic_context_from_args (&context
, type_args
, method_args
);
5451 method
= mono_get_method_full (image
, token
, NULL
, &context
);
5453 if (mono_loader_get_last_error ())
5454 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5460 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5462 int index
= mono_metadata_token_index (token
);
5464 *error
= ResolveTokenError_Other
;
5466 /* Validate token */
5467 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5468 *error
= ResolveTokenError_BadTable
;
5473 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5475 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5476 *error
= ResolveTokenError_OutOfRange
;
5480 /* FIXME: What to do if the index points into the middle of a string ? */
5482 return mono_ldstr (mono_domain_get (), image
, index
);
5485 static MonoClassField
*
5486 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5489 int table
= mono_metadata_token_table (token
);
5490 int index
= mono_metadata_token_index (token
);
5491 MonoGenericContext context
;
5492 MonoClassField
*field
;
5494 *error
= ResolveTokenError_Other
;
5496 /* Validate token */
5497 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
5498 *error
= ResolveTokenError_BadTable
;
5502 if (image
->dynamic
) {
5503 if (type_args
|| method_args
)
5504 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5505 /* FIXME: validate memberref token type */
5506 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5509 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5510 *error
= ResolveTokenError_OutOfRange
;
5513 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_metadata_memberref_is_method (image
, token
))) {
5514 *error
= ResolveTokenError_BadTable
;
5518 init_generic_context_from_args (&context
, type_args
, method_args
);
5519 field
= mono_field_from_token (image
, token
, &klass
, &context
);
5521 if (mono_loader_get_last_error ())
5522 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5529 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5531 int table
= mono_metadata_token_table (token
);
5533 *error
= ResolveTokenError_Other
;
5536 case MONO_TABLE_TYPEDEF
:
5537 case MONO_TABLE_TYPEREF
:
5538 case MONO_TABLE_TYPESPEC
: {
5539 MonoType
*t
= ves_icall_System_Reflection_Module_ResolveTypeToken (image
, token
, type_args
, method_args
, error
);
5541 return (MonoObject
*)mono_type_get_object (mono_domain_get (), t
);
5545 case MONO_TABLE_METHOD
:
5546 case MONO_TABLE_METHODSPEC
: {
5547 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5549 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5553 case MONO_TABLE_FIELD
: {
5554 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5556 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5560 case MONO_TABLE_MEMBERREF
:
5561 if (mono_metadata_memberref_is_method (image
, token
)) {
5562 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5564 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5569 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5571 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5578 *error
= ResolveTokenError_BadTable
;
5585 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5587 int table
= mono_metadata_token_table (token
);
5588 int idx
= mono_metadata_token_index (token
);
5589 MonoTableInfo
*tables
= image
->tables
;
5594 *error
= ResolveTokenError_OutOfRange
;
5596 /* FIXME: Support other tables ? */
5597 if (table
!= MONO_TABLE_STANDALONESIG
)
5603 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
5606 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
5608 ptr
= mono_metadata_blob_heap (image
, sig
);
5609 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
5611 res
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, len
);
5612 memcpy (mono_array_addr (res
, guint8
, 0), ptr
, len
);
5616 static MonoReflectionType
*
5617 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder
*tb
, MonoString
*smodifiers
)
5620 int isbyref
= 0, rank
;
5621 char *str
= mono_string_to_utf8 (smodifiers
);
5624 MONO_ARCH_SAVE_REGS
;
5626 klass
= mono_class_from_mono_type (tb
->type
.type
);
5628 /* logic taken from mono_reflection_parse_type(): keep in sync */
5632 if (isbyref
) { /* only one level allowed by the spec */
5639 return mono_type_get_object (mono_object_domain (tb
), &klass
->this_arg
);
5642 klass
= mono_ptr_class_get (&klass
->byval_arg
);
5643 mono_class_init (klass
);
5654 else if (*p
!= '*') { /* '*' means unknown lower bound */
5665 klass
= mono_array_class_get (klass
, rank
);
5666 mono_class_init (klass
);
5673 return mono_type_get_object (mono_object_domain (tb
), &klass
->byval_arg
);
5677 ves_icall_Type_IsArrayImpl (MonoReflectionType
*t
)
5682 MONO_ARCH_SAVE_REGS
;
5685 res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
5690 static MonoReflectionType
*
5691 ves_icall_Type_make_array_type (MonoReflectionType
*type
, int rank
)
5693 MonoClass
*klass
, *aklass
;
5695 MONO_ARCH_SAVE_REGS
;
5697 klass
= mono_class_from_mono_type (type
->type
);
5698 if (rank
== 0) //single dimentional array
5699 aklass
= mono_array_class_get (klass
, 1);
5701 aklass
= mono_bounded_array_class_get (klass
, rank
, TRUE
);
5703 return mono_type_get_object (mono_object_domain (type
), &aklass
->byval_arg
);
5706 static MonoReflectionType
*
5707 ves_icall_Type_make_byref_type (MonoReflectionType
*type
)
5711 MONO_ARCH_SAVE_REGS
;
5713 klass
= mono_class_from_mono_type (type
->type
);
5715 return mono_type_get_object (mono_object_domain (type
), &klass
->this_arg
);
5718 static MonoReflectionType
*
5719 ves_icall_Type_MakePointerType (MonoReflectionType
*type
)
5723 MONO_ARCH_SAVE_REGS
;
5725 pklass
= mono_ptr_class_get (type
->type
);
5727 return mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
);
5731 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType
*type
, MonoObject
*target
,
5732 MonoReflectionMethod
*info
, MonoBoolean throwOnBindFailure
)
5734 MonoClass
*delegate_class
= mono_class_from_mono_type (type
->type
);
5735 MonoObject
*delegate
;
5737 MonoMethod
*method
= info
->method
;
5739 MONO_ARCH_SAVE_REGS
;
5741 mono_assert (delegate_class
->parent
== mono_defaults
.multicastdelegate_class
);
5743 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
) {
5744 if (!mono_security_core_clr_ensure_delegate_creation (method
, throwOnBindFailure
))
5748 delegate
= mono_object_new (mono_object_domain (type
), delegate_class
);
5750 if (method
->dynamic
) {
5751 /* Creating a trampoline would leak memory */
5752 func
= mono_compile_method (method
);
5754 func
= mono_create_ftnptr (mono_domain_get (),
5755 mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
));
5758 mono_delegate_ctor_with_method (delegate
, target
, func
, method
);
5764 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate
*this)
5766 /* Reset the invoke impl to the default one */
5767 this->invoke_impl
= mono_runtime_create_delegate_trampoline (this->object
.vtable
->klass
);
5771 * Magic number to convert a time which is relative to
5772 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5774 #define EPOCH_ADJUST ((guint64)62135596800LL)
5777 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5779 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5782 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5784 convert_to_absolute_date(SYSTEMTIME
*date
)
5786 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5787 static int days_in_month
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5788 static int leap_days_in_month
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5789 /* from the calendar FAQ */
5790 int a
= (14 - date
->wMonth
) / 12;
5791 int y
= date
->wYear
- a
;
5792 int m
= date
->wMonth
+ 12 * a
- 2;
5793 int d
= (1 + y
+ y
/4 - y
/100 + y
/400 + (31*m
)/12) % 7;
5795 /* d is now the day of the week for the first of the month (0 == Sunday) */
5797 int day_of_week
= date
->wDayOfWeek
;
5799 /* set day_in_month to the first day in the month which falls on day_of_week */
5800 int day_in_month
= 1 + (day_of_week
- d
);
5801 if (day_in_month
<= 0)
5804 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5805 date
->wDay
= day_in_month
+ (date
->wDay
- 1) * 7;
5806 if (date
->wDay
> (IS_LEAP(date
->wYear
) ? leap_days_in_month
[date
->wMonth
- 1] : days_in_month
[date
->wMonth
- 1]))
5813 * Return's the offset from GMT of a local time.
5815 * tm is a local time
5816 * t is the same local time as seconds.
5819 gmt_offset(struct tm
*tm
, time_t t
)
5821 #if defined (HAVE_TM_GMTOFF)
5822 return tm
->tm_gmtoff
;
5827 g
.tm_isdst
= tm
->tm_isdst
;
5829 return (int)difftime(t
, t2
);
5834 * This is heavily based on zdump.c from glibc 2.2.
5836 * * data[0]: start of daylight saving time (in DateTime ticks).
5837 * * data[1]: end of daylight saving time (in DateTime ticks).
5838 * * data[2]: utcoffset (in TimeSpan ticks).
5839 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5840 * * name[0]: name of this timezone when not daylight saving.
5841 * * name[1]: name of this timezone when daylight saving.
5843 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5844 * the class library allows years between 1 and 9999.
5846 * Returns true on success and zero on failure.
5849 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year
, MonoArray
**data
, MonoArray
**names
)
5852 MonoDomain
*domain
= mono_domain_get ();
5853 struct tm start
, tt
;
5857 int is_daylight
= 0, day
;
5860 MONO_ARCH_SAVE_REGS
;
5862 MONO_CHECK_ARG_NULL (data
);
5863 MONO_CHECK_ARG_NULL (names
);
5865 mono_gc_wbarrier_generic_store (data
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5866 mono_gc_wbarrier_generic_store (names
, (MonoObject
*) mono_array_new (domain
, mono_defaults
.string_class
, 2));
5869 * no info is better than crashing: we'll need our own tz data
5870 * to make this work properly, anyway. The range is probably
5871 * reduced to 1970 .. 2037 because that is what mktime is
5872 * guaranteed to support (we get into an infinite loop
5876 memset (&start
, 0, sizeof (start
));
5879 start
.tm_year
= year
-1900;
5881 t
= mktime (&start
);
5883 if ((year
< 1970) || (year
> 2037) || (t
== -1)) {
5885 tt
= *localtime (&t
);
5886 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5887 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5888 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5892 gmtoff
= gmt_offset (&start
, t
);
5894 /* For each day of the year, calculate the tm_gmtoff. */
5895 for (day
= 0; day
< 365; day
++) {
5898 tt
= *localtime (&t
);
5900 /* Daylight saving starts or ends here. */
5901 if (gmt_offset (&tt
, t
) != gmtoff
) {
5905 /* Try to find the exact hour when daylight saving starts/ends. */
5909 tt1
= *localtime (&t1
);
5910 } while (gmt_offset (&tt1
, t1
) != gmtoff
);
5912 /* Try to find the exact minute when daylight saving starts/ends. */
5915 tt1
= *localtime (&t1
);
5916 } while (gmt_offset (&tt1
, t1
) == gmtoff
);
5918 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5920 /* Write data, if we're already in daylight saving, we're done. */
5922 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5923 mono_array_set ((*data
), gint64
, 1, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5926 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5927 mono_array_set ((*data
), gint64
, 0, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
5931 /* This is only set once when we enter daylight saving. */
5932 mono_array_set ((*data
), gint64
, 2, (gint64
)gmtoff
* 10000000L);
5933 mono_array_set ((*data
), gint64
, 3, (gint64
)(gmt_offset (&tt
, t
) - gmtoff
) * 10000000L);
5935 gmtoff
= gmt_offset (&tt
, t
);
5940 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
5941 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
5942 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
5943 mono_array_set ((*data
), gint64
, 0, 0);
5944 mono_array_set ((*data
), gint64
, 1, 0);
5945 mono_array_set ((*data
), gint64
, 2, (gint64
) gmtoff
* 10000000L);
5946 mono_array_set ((*data
), gint64
, 3, 0);
5951 MonoDomain
*domain
= mono_domain_get ();
5952 TIME_ZONE_INFORMATION tz_info
;
5957 tz_id
= GetTimeZoneInformation (&tz_info
);
5958 if (tz_id
== TIME_ZONE_ID_INVALID
)
5961 MONO_CHECK_ARG_NULL (data
);
5962 MONO_CHECK_ARG_NULL (names
);
5964 mono_gc_wbarrier_generic_store (data
, mono_array_new (domain
, mono_defaults
.int64_class
, 4));
5965 mono_gc_wbarrier_generic_store (names
, mono_array_new (domain
, mono_defaults
.string_class
, 2));
5967 for (i
= 0; i
< 32; ++i
)
5968 if (!tz_info
.DaylightName
[i
])
5970 mono_array_setref ((*names
), 1, mono_string_new_utf16 (domain
, tz_info
.DaylightName
, i
));
5971 for (i
= 0; i
< 32; ++i
)
5972 if (!tz_info
.StandardName
[i
])
5974 mono_array_setref ((*names
), 0, mono_string_new_utf16 (domain
, tz_info
.StandardName
, i
));
5976 if ((year
<= 1601) || (year
> 30827)) {
5978 * According to MSDN, the MS time functions can't handle dates outside
5984 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5985 if (tz_id
!= TIME_ZONE_ID_UNKNOWN
) {
5986 tz_info
.StandardDate
.wYear
= year
;
5987 convert_to_absolute_date(&tz_info
.StandardDate
);
5988 err
= SystemTimeToFileTime (&tz_info
.StandardDate
, &ft
);
5993 mono_array_set ((*data
), gint64
, 1, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
5994 tz_info
.DaylightDate
.wYear
= year
;
5995 convert_to_absolute_date(&tz_info
.DaylightDate
);
5996 err
= SystemTimeToFileTime (&tz_info
.DaylightDate
, &ft
);
6001 mono_array_set ((*data
), gint64
, 0, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
6003 mono_array_set ((*data
), gint64
, 2, (tz_info
.Bias
+ tz_info
.StandardBias
) * -600000000LL);
6004 mono_array_set ((*data
), gint64
, 3, (tz_info
.DaylightBias
- tz_info
.StandardBias
) * -600000000LL);
6011 ves_icall_System_Object_obj_address (MonoObject
*this)
6013 MONO_ARCH_SAVE_REGS
;
6020 static inline gint32
6021 mono_array_get_byte_length (MonoArray
*array
)
6027 klass
= array
->obj
.vtable
->klass
;
6029 if (array
->bounds
== NULL
)
6030 length
= array
->max_length
;
6033 for (i
= 0; i
< klass
->rank
; ++ i
)
6034 length
*= array
->bounds
[i
].length
;
6037 switch (klass
->element_class
->byval_arg
.type
) {
6040 case MONO_TYPE_BOOLEAN
:
6044 case MONO_TYPE_CHAR
:
6052 return length
* sizeof (gpointer
);
6063 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6065 MONO_ARCH_SAVE_REGS
;
6067 return mono_array_get_byte_length (array
);
6071 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6073 MONO_ARCH_SAVE_REGS
;
6075 return mono_array_get (array
, gint8
, idx
);
6079 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6081 MONO_ARCH_SAVE_REGS
;
6083 mono_array_set (array
, gint8
, idx
, value
);
6087 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6089 guint8
*src_buf
, *dest_buf
;
6091 MONO_ARCH_SAVE_REGS
;
6093 /* watch out for integer overflow */
6094 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6097 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6098 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6101 memcpy (dest_buf
, src_buf
, count
);
6103 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6109 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject
*this, MonoString
*class_name
)
6111 MonoDomain
*domain
= mono_object_domain (this);
6113 MonoRealProxy
*rp
= ((MonoRealProxy
*)this);
6114 MonoTransparentProxy
*tp
;
6118 MONO_ARCH_SAVE_REGS
;
6120 res
= mono_object_new (domain
, mono_defaults
.transparent_proxy_class
);
6121 tp
= (MonoTransparentProxy
*) res
;
6123 MONO_OBJECT_SETREF (tp
, rp
, rp
);
6124 type
= ((MonoReflectionType
*)rp
->class_to_proxy
)->type
;
6125 klass
= mono_class_from_mono_type (type
);
6127 tp
->custom_type_info
= (mono_object_isinst (this, mono_defaults
.iremotingtypeinfo_class
) != NULL
);
6128 tp
->remote_class
= mono_remote_class (domain
, class_name
, klass
);
6130 res
->vtable
= mono_remote_class_vtable (domain
, tp
->remote_class
, rp
);
6134 static MonoReflectionType
*
6135 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6137 return mono_type_get_object (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
);
6140 /* System.Environment */
6143 ves_icall_System_Environment_get_UserName (void)
6145 MONO_ARCH_SAVE_REGS
;
6147 /* using glib is more portable */
6148 return mono_string_new (mono_domain_get (), g_get_user_name ());
6153 ves_icall_System_Environment_get_MachineName (void)
6155 #if defined (HOST_WIN32)
6160 len
= MAX_COMPUTERNAME_LENGTH
+ 1;
6161 buf
= g_new (gunichar2
, len
);
6164 if (GetComputerName (buf
, (PDWORD
) &len
))
6165 result
= mono_string_new_utf16 (mono_domain_get (), buf
, len
);
6169 #elif !defined(DISABLE_SOCKETS)
6173 if (gethostname (buf
, sizeof (buf
)) == 0)
6174 result
= mono_string_new (mono_domain_get (), buf
);
6180 return mono_string_new (mono_domain_get (), "mono");
6185 ves_icall_System_Environment_get_Platform (void)
6187 #if defined (TARGET_WIN32)
6190 #elif defined(__MACH__)
6192 if (mono_framework_version () < 2)
6196 // For compatibility with our client code, this will be 4 for a while.
6197 // We will eventually move to 6 to match .NET, but it requires all client
6198 // code to be updated and the documentation everywhere to be updated
6204 if (mono_framework_version () < 2)
6211 ves_icall_System_Environment_get_NewLine (void)
6213 MONO_ARCH_SAVE_REGS
;
6215 #if defined (HOST_WIN32)
6216 return mono_string_new (mono_domain_get (), "\r\n");
6218 return mono_string_new (mono_domain_get (), "\n");
6223 ves_icall_System_Environment_GetEnvironmentVariable (MonoString
*name
)
6228 MONO_ARCH_SAVE_REGS
;
6233 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6234 value
= g_getenv (utf8_name
);
6241 return mono_string_new (mono_domain_get (), value
);
6245 * There is no standard way to get at environ.
6248 #ifndef __MINGW32_VERSION
6250 /* Apple defines this in crt_externs.h but doesn't provide that header for
6251 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6252 * in fact exist on all implementations (so far)
6254 gchar
***_NSGetEnviron(void);
6255 #define environ (*_NSGetEnviron())
6264 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6275 env_strings
= GetEnvironmentStrings();
6278 env_string
= env_strings
;
6279 while (*env_string
!= '\0') {
6280 /* weird case that MS seems to skip */
6281 if (*env_string
!= '=')
6283 while (*env_string
!= '\0')
6289 domain
= mono_domain_get ();
6290 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6294 env_string
= env_strings
;
6295 while (*env_string
!= '\0') {
6296 /* weird case that MS seems to skip */
6297 if (*env_string
!= '=') {
6298 equal_str
= wcschr(env_string
, '=');
6299 g_assert(equal_str
);
6300 str
= mono_string_new_utf16 (domain
, env_string
, equal_str
-env_string
);
6301 mono_array_setref (names
, n
, str
);
6304 while (*env_string
!= '\0')
6309 FreeEnvironmentStrings (env_strings
);
6321 MONO_ARCH_SAVE_REGS
;
6324 for (e
= environ
; *e
!= 0; ++ e
)
6327 domain
= mono_domain_get ();
6328 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6331 for (e
= environ
; *e
!= 0; ++ e
) {
6332 parts
= g_strsplit (*e
, "=", 2);
6334 str
= mono_string_new (domain
, *parts
);
6335 mono_array_setref (names
, n
, str
);
6348 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6350 #if !GLIB_CHECK_VERSION(2,4,0)
6351 #define g_setenv(a,b,c) setenv(a,b,c)
6352 #define g_unsetenv(a) unsetenv(a)
6356 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6361 gunichar2
*utf16_name
, *utf16_value
;
6363 gchar
*utf8_name
, *utf8_value
;
6366 MONO_ARCH_SAVE_REGS
;
6369 utf16_name
= mono_string_to_utf16 (name
);
6370 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6371 SetEnvironmentVariable (utf16_name
, NULL
);
6372 g_free (utf16_name
);
6376 utf16_value
= mono_string_to_utf16 (value
);
6378 SetEnvironmentVariable (utf16_name
, utf16_value
);
6380 g_free (utf16_name
);
6381 g_free (utf16_value
);
6383 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6385 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6386 g_unsetenv (utf8_name
);
6391 utf8_value
= mono_string_to_utf8_checked (value
, &error
);
6392 if (!mono_error_ok (&error
)) {
6394 mono_error_raise_exception (&error
);
6396 g_setenv (utf8_name
, utf8_value
, TRUE
);
6399 g_free (utf8_value
);
6404 ves_icall_System_Environment_Exit (int result
)
6406 MONO_ARCH_SAVE_REGS
;
6408 mono_threads_set_shutting_down ();
6410 mono_runtime_set_shutting_down ();
6412 /* Suspend all managed threads since the runtime is going away */
6413 mono_thread_suspend_all_other_threads ();
6415 mono_runtime_quit ();
6417 /* we may need to do some cleanup here... */
6422 ves_icall_System_Environment_GetGacPath (void)
6424 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6428 ves_icall_System_Environment_GetWindowsFolderPath (int folder
)
6430 #if defined (HOST_WIN32)
6431 #ifndef CSIDL_FLAG_CREATE
6432 #define CSIDL_FLAG_CREATE 0x8000
6435 WCHAR path
[MAX_PATH
];
6436 /* Create directory if no existing */
6437 if (SUCCEEDED (SHGetFolderPathW (NULL
, folder
| CSIDL_FLAG_CREATE
, NULL
, 0, path
))) {
6441 return mono_string_new_utf16 (mono_domain_get (), path
, len
);
6444 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6446 return mono_string_new (mono_domain_get (), "");
6450 ves_icall_System_Environment_GetLogicalDrives (void)
6452 gunichar2 buf
[128], *ptr
, *dname
;
6454 guint initial_size
= 127, size
= 128;
6457 MonoString
*drivestr
;
6458 MonoDomain
*domain
= mono_domain_get ();
6461 MONO_ARCH_SAVE_REGS
;
6466 while (size
> initial_size
) {
6467 size
= (guint
) GetLogicalDriveStrings (initial_size
, ptr
);
6468 if (size
> initial_size
) {
6471 ptr
= g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6472 initial_size
= size
;
6486 result
= mono_array_new (domain
, mono_defaults
.string_class
, ndrives
);
6491 while (*u16
) { u16
++; len
++; }
6492 drivestr
= mono_string_new_utf16 (domain
, dname
, len
);
6493 mono_array_setref (result
, ndrives
++, drivestr
);
6504 ves_icall_System_Environment_InternalGetHome (void)
6506 MONO_ARCH_SAVE_REGS
;
6508 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6511 static const char *encodings
[] = {
6513 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6514 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6515 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6517 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6518 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6519 "x_unicode_2_0_utf_7",
6521 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6522 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6524 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6527 "unicodefffe", "utf_16be",
6534 * Returns the internal codepage, if the value of "int_code_page" is
6535 * 1 at entry, and we can not compute a suitable code page number,
6536 * returns the code page as a string
6539 ves_icall_System_Text_Encoding_InternalCodePage (gint32
*int_code_page
)
6544 char *codepage
= NULL
;
6546 int want_name
= *int_code_page
;
6549 *int_code_page
= -1;
6550 MONO_ARCH_SAVE_REGS
;
6552 g_get_charset (&cset
);
6553 c
= codepage
= strdup (cset
);
6554 for (c
= codepage
; *c
; c
++){
6555 if (isascii (*c
) && isalpha (*c
))
6560 /* g_print ("charset: %s\n", cset); */
6562 /* handle some common aliases */
6565 for (i
= 0; p
!= 0; ){
6566 if ((gssize
) p
< 7){
6568 p
= encodings
[++i
];
6571 if (strcmp (p
, codepage
) == 0){
6572 *int_code_page
= code
;
6575 p
= encodings
[++i
];
6578 if (strstr (codepage
, "utf_8") != NULL
)
6579 *int_code_page
|= 0x10000000;
6582 if (want_name
&& *int_code_page
== -1)
6583 return mono_string_new (mono_domain_get (), cset
);
6589 ves_icall_System_Environment_get_HasShutdownStarted (void)
6591 if (mono_runtime_is_shutting_down ())
6594 if (mono_domain_is_unloading (mono_domain_get ()))
6601 ves_icall_System_Environment_BroadcastSettingChange (void)
6604 SendMessageTimeout (HWND_BROADCAST
, WM_SETTINGCHANGE
, NULL
, L
"Environment", SMTO_ABORTIFHUNG
, 2000, 0);
6609 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage
*this,
6610 MonoReflectionMethod
*method
,
6611 MonoArray
*out_args
)
6613 MONO_ARCH_SAVE_REGS
;
6615 mono_message_init (mono_object_domain (this), this, method
, out_args
);
6619 ves_icall_IsTransparentProxy (MonoObject
*proxy
)
6621 MONO_ARCH_SAVE_REGS
;
6626 if (proxy
->vtable
->klass
== mono_defaults
.transparent_proxy_class
)
6632 static MonoReflectionMethod
*
6633 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6634 MonoReflectionType
*rtype
, MonoReflectionMethod
*rmethod
)
6638 MonoMethod
**vtable
;
6639 MonoMethod
*res
= NULL
;
6641 MONO_CHECK_ARG_NULL (rtype
);
6642 MONO_CHECK_ARG_NULL (rmethod
);
6644 method
= rmethod
->method
;
6645 klass
= mono_class_from_mono_type (rtype
->type
);
6647 if (MONO_CLASS_IS_INTERFACE (klass
))
6650 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
6653 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
6654 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
6660 mono_class_setup_vtable (klass
);
6661 vtable
= klass
->vtable
;
6663 if (method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
) {
6664 gboolean variance_used
= FALSE
;
6665 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6666 int offs
= mono_class_interface_offset_with_variance (klass
, method
->klass
, &variance_used
);
6668 res
= vtable
[offs
+ method
->slot
];
6670 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
6673 if (method
->slot
!= -1)
6674 res
= vtable
[method
->slot
];
6680 return mono_method_get_object (mono_domain_get (), res
, NULL
);
6684 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType
*type
, MonoBoolean enable
)
6689 MONO_ARCH_SAVE_REGS
;
6691 klass
= mono_class_from_mono_type (type
->type
);
6692 vtable
= mono_class_vtable_full (mono_domain_get (), klass
, TRUE
);
6694 if (enable
) vtable
->remote
= 1;
6695 else vtable
->remote
= 0;
6699 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType
*type
)
6704 MONO_ARCH_SAVE_REGS
;
6706 domain
= mono_object_domain (type
);
6707 klass
= mono_class_from_mono_type (type
->type
);
6709 if (klass
->rank
>= 1) {
6710 g_assert (klass
->rank
== 1);
6711 return (MonoObject
*) mono_array_new (domain
, klass
->element_class
, 0);
6713 /* Bypass remoting object creation check */
6714 return mono_object_new_alloc_specific (mono_class_vtable_full (domain
, klass
, TRUE
));
6719 ves_icall_System_IO_get_temp_path (void)
6721 MONO_ARCH_SAVE_REGS
;
6723 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6726 #ifndef PLATFORM_NO_DRIVEINFO
6728 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString
*path_name
, guint64
*free_bytes_avail
,
6729 guint64
*total_number_of_bytes
, guint64
*total_number_of_free_bytes
,
6733 ULARGE_INTEGER wapi_free_bytes_avail
;
6734 ULARGE_INTEGER wapi_total_number_of_bytes
;
6735 ULARGE_INTEGER wapi_total_number_of_free_bytes
;
6737 MONO_ARCH_SAVE_REGS
;
6739 *error
= ERROR_SUCCESS
;
6740 result
= GetDiskFreeSpaceEx (mono_string_chars (path_name
), &wapi_free_bytes_avail
, &wapi_total_number_of_bytes
,
6741 &wapi_total_number_of_free_bytes
);
6744 *free_bytes_avail
= wapi_free_bytes_avail
.QuadPart
;
6745 *total_number_of_bytes
= wapi_total_number_of_bytes
.QuadPart
;
6746 *total_number_of_free_bytes
= wapi_total_number_of_free_bytes
.QuadPart
;
6748 *free_bytes_avail
= 0;
6749 *total_number_of_bytes
= 0;
6750 *total_number_of_free_bytes
= 0;
6751 *error
= GetLastError ();
6758 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString
*root_path_name
)
6760 MONO_ARCH_SAVE_REGS
;
6762 return GetDriveType (mono_string_chars (root_path_name
));
6767 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod
*method
)
6769 MONO_ARCH_SAVE_REGS
;
6771 return mono_compile_method (method
);
6775 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6780 MONO_ARCH_SAVE_REGS
;
6782 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
6784 #if defined (HOST_WIN32)
6785 /* Avoid mixing '/' and '\\' */
6788 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6789 if (path
[i
] == '/')
6793 mcpath
= mono_string_new (mono_domain_get (), path
);
6800 get_bundled_machine_config (void)
6802 const gchar
*machine_config
;
6804 MONO_ARCH_SAVE_REGS
;
6806 machine_config
= mono_get_machine_config ();
6808 if (!machine_config
)
6811 return mono_string_new (mono_domain_get (), machine_config
);
6815 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6820 MONO_ARCH_SAVE_REGS
;
6822 path
= g_path_get_dirname (mono_get_config_dir ());
6824 #if defined (HOST_WIN32)
6825 /* Avoid mixing '/' and '\\' */
6828 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6829 if (path
[i
] == '/')
6833 ipath
= mono_string_new (mono_domain_get (), path
);
6840 ves_icall_get_resources_ptr (MonoReflectionAssembly
*assembly
, gpointer
*result
, gint32
*size
)
6842 MonoPEResourceDataEntry
*entry
;
6845 MONO_ARCH_SAVE_REGS
;
6847 if (!assembly
|| !result
|| !size
)
6852 image
= assembly
->assembly
->image
;
6853 entry
= mono_image_lookup_resource (image
, MONO_PE_RESOURCE_ID_ASPNET_STRING
, 0, NULL
);
6857 *result
= mono_image_rva_map (image
, entry
->rde_data_offset
);
6862 *size
= entry
->rde_size
;
6868 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
6870 return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
6874 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
6876 #if defined (HOST_WIN32)
6877 OutputDebugString (mono_string_chars (message
));
6879 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
6883 /* Only used for value types */
6885 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType
*type
)
6890 MONO_ARCH_SAVE_REGS
;
6892 domain
= mono_object_domain (type
);
6893 klass
= mono_class_from_mono_type (type
->type
);
6895 if (mono_class_is_nullable (klass
))
6896 /* No arguments -> null */
6899 return mono_object_new (domain
, klass
);
6902 static MonoReflectionMethod
*
6903 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod
*m
, gboolean definition
)
6905 MonoClass
*klass
, *parent
;
6906 MonoMethod
*method
= m
->method
;
6907 MonoMethod
*result
= NULL
;
6909 MONO_ARCH_SAVE_REGS
;
6911 if (method
->klass
== NULL
)
6914 if (!(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
) ||
6915 MONO_CLASS_IS_INTERFACE (method
->klass
) ||
6916 method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
)
6919 klass
= method
->klass
;
6920 if (klass
->generic_class
)
6921 klass
= klass
->generic_class
->container_class
;
6924 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6925 for (parent
= klass
->parent
; parent
!= NULL
; parent
= parent
->parent
) {
6926 mono_class_setup_vtable (parent
);
6927 if (parent
->vtable_size
<= method
->slot
)
6932 klass
= klass
->parent
;
6937 if (klass
== method
->klass
)
6940 result
= klass
->vtable
[method
->slot
];
6941 if (result
== NULL
) {
6942 /* It is an abstract method */
6943 gpointer iter
= NULL
;
6944 while ((result
= mono_class_get_methods (klass
, &iter
)))
6945 if (result
->slot
== method
->slot
)
6952 return mono_method_get_object (mono_domain_get (), result
, NULL
);
6956 ves_icall_MonoMethod_get_name (MonoReflectionMethod
*m
)
6958 MonoMethod
*method
= m
->method
;
6960 MONO_OBJECT_SETREF (m
, name
, mono_string_new (mono_object_domain (m
), method
->name
));
6965 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
6967 MONO_ARCH_SAVE_REGS
;
6969 iter
->sig
= *(MonoMethodSignature
**)argsp
;
6971 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
6972 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
6975 /* FIXME: it's not documented what start is exactly... */
6979 iter
->args
= argsp
+ sizeof (gpointer
);
6981 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
6983 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6987 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
6989 guint32 i
, arg_size
;
6992 MONO_ARCH_SAVE_REGS
;
6994 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
6996 g_assert (i
< iter
->sig
->param_count
);
6998 res
.type
= iter
->sig
->params
[i
];
6999 res
.klass
= mono_class_from_mono_type (res
.type
);
7000 res
.value
= iter
->args
;
7001 arg_size
= mono_type_stack_size (res
.type
, &align
);
7002 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7003 if (arg_size
<= sizeof (gpointer
)) {
7005 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
7006 res
.value
= (guint8
*)res
.value
+ padding
;
7009 iter
->args
= (char*)iter
->args
+ arg_size
;
7012 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7018 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
7020 guint32 i
, arg_size
;
7023 MONO_ARCH_SAVE_REGS
;
7025 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7027 g_assert (i
< iter
->sig
->param_count
);
7029 while (i
< iter
->sig
->param_count
) {
7030 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
7032 res
.type
= iter
->sig
->params
[i
];
7033 res
.klass
= mono_class_from_mono_type (res
.type
);
7034 /* FIXME: endianess issue... */
7035 res
.value
= iter
->args
;
7036 arg_size
= mono_type_stack_size (res
.type
, &align
);
7037 iter
->args
= (char*)iter
->args
+ arg_size
;
7039 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7042 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7051 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7054 MONO_ARCH_SAVE_REGS
;
7056 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7058 g_assert (i
< iter
->sig
->param_count
);
7060 return iter
->sig
->params
[i
];
7064 mono_TypedReference_ToObject (MonoTypedRef tref
)
7066 MONO_ARCH_SAVE_REGS
;
7068 if (MONO_TYPE_IS_REFERENCE (tref
.type
)) {
7069 MonoObject
** objp
= tref
.value
;
7073 return mono_value_box (mono_domain_get (), tref
.klass
, tref
.value
);
7077 mono_TypedReference_ToObjectInternal (MonoType
*type
, gpointer value
, MonoClass
*klass
)
7079 MONO_ARCH_SAVE_REGS
;
7081 if (MONO_TYPE_IS_REFERENCE (type
)) {
7082 MonoObject
** objp
= value
;
7086 return mono_value_box (mono_domain_get (), klass
, value
);
7090 prelink_method (MonoMethod
*method
)
7092 const char *exc_class
, *exc_arg
;
7093 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7095 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7097 mono_raise_exception(
7098 mono_exception_from_name_msg (mono_defaults
.corlib
, "System", exc_class
, exc_arg
) );
7100 /* create the wrapper, too? */
7104 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod
*method
)
7106 MONO_ARCH_SAVE_REGS
;
7107 prelink_method (method
->method
);
7111 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
*type
)
7113 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
7115 gpointer iter
= NULL
;
7116 MONO_ARCH_SAVE_REGS
;
7118 while ((m
= mono_class_get_methods (klass
, &iter
)))
7122 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7124 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7125 gint32
const **exponents
,
7126 gunichar2
const **digitLowerTable
,
7127 gunichar2
const **digitUpperTable
,
7128 gint64
const **tenPowersList
,
7129 gint32
const **decHexDigits
)
7131 *mantissas
= Formatter_MantissaBitsTable
;
7132 *exponents
= Formatter_TensExponentTable
;
7133 *digitLowerTable
= Formatter_DigitLowerTable
;
7134 *digitUpperTable
= Formatter_DigitUpperTable
;
7135 *tenPowersList
= Formatter_TenPowersList
;
7136 *decHexDigits
= Formatter_DecHexDigits
;
7139 /* These parameters are "readonly" in corlib/System/Char.cs */
7141 ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data
,
7142 guint8
const **numeric_data
,
7143 gdouble
const **numeric_data_values
,
7144 guint16
const **to_lower_data_low
,
7145 guint16
const **to_lower_data_high
,
7146 guint16
const **to_upper_data_low
,
7147 guint16
const **to_upper_data_high
)
7149 *category_data
= CategoryData
;
7150 *numeric_data
= NumericData
;
7151 *numeric_data_values
= NumericDataValues
;
7152 *to_lower_data_low
= ToLowerDataLow
;
7153 *to_lower_data_high
= ToLowerDataHigh
;
7154 *to_upper_data_low
= ToUpperDataLow
;
7155 *to_upper_data_high
= ToUpperDataHigh
;
7159 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod
*method
)
7161 return method
->method
->token
;
7165 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7166 * and avoid useless allocations.
7169 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
)
7173 for (i
= 0; i
< type
->num_mods
; ++i
) {
7174 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7179 res
= mono_array_new (mono_domain_get (), mono_defaults
.systemtype_class
, count
);
7181 for (i
= 0; i
< type
->num_mods
; ++i
) {
7182 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7183 MonoClass
*klass
= mono_class_get (image
, type
->modifiers
[i
].token
);
7184 mono_array_setref (res
, count
, mono_type_get_object (mono_domain_get (), &klass
->byval_arg
));
7192 param_info_get_type_modifiers (MonoReflectionParameter
*param
, MonoBoolean optional
)
7194 MonoType
*type
= param
->ClassImpl
->type
;
7195 MonoReflectionMethod
*method
= (MonoReflectionMethod
*)param
->MemberImpl
;
7196 MonoImage
*image
= method
->method
->klass
->image
;
7197 int pos
= param
->PositionImpl
;
7198 MonoMethodSignature
*sig
= mono_method_signature (method
->method
);
7202 type
= sig
->params
[pos
];
7204 return type_array_from_modifiers (image
, type
, optional
);
7208 get_property_type (MonoProperty
*prop
)
7210 MonoMethodSignature
*sig
;
7212 sig
= mono_method_signature (prop
->get
);
7214 } else if (prop
->set
) {
7215 sig
= mono_method_signature (prop
->set
);
7216 return sig
->params
[sig
->param_count
- 1];
7222 property_info_get_type_modifiers (MonoReflectionProperty
*property
, MonoBoolean optional
)
7224 MonoType
*type
= get_property_type (property
->property
);
7225 MonoImage
*image
= property
->klass
->image
;
7229 return type_array_from_modifiers (image
, type
, optional
);
7233 custom_attrs_defined_internal (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7235 MonoCustomAttrInfo
*cinfo
;
7238 cinfo
= mono_reflection_get_custom_attrs_info (obj
);
7241 found
= mono_custom_attrs_has_attr (cinfo
, mono_class_from_mono_type (attr_type
->type
));
7243 mono_custom_attrs_free (cinfo
);
7248 custom_attrs_get_by_type (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7250 MonoArray
*res
= mono_reflection_get_custom_attrs_by_type (obj
, attr_type
? mono_class_from_mono_type (attr_type
->type
) : NULL
);
7252 if (mono_loader_get_last_error ()) {
7253 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7254 g_assert_not_reached ();
7263 ves_icall_Mono_Runtime_GetDisplayName (void)
7266 MonoString
*display_name
;
7268 info
= mono_get_runtime_callbacks ()->get_runtime_build_info ();
7269 display_name
= mono_string_new (mono_domain_get (), info
);
7271 return display_name
;
7275 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code
)
7277 MonoString
*message
;
7281 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
7282 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, code
, 0,
7285 message
= mono_string_new (mono_domain_get (), "Error looking up error string");
7287 message
= mono_string_new_utf16 (mono_domain_get (), buf
, ret
);
7295 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7296 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7297 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7298 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7299 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7300 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7301 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7302 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7306 base64_to_byte_array (gunichar2
*start
, gint ilength
, MonoBoolean allowWhitespaceOnly
)
7311 gunichar2 last
, prev_last
, prev2_last
;
7319 last
= prev_last
= 0, prev2_last
= 0;
7320 for (i
= 0; i
< ilength
; i
++) {
7322 if (c
>= sizeof (dbase64
)) {
7323 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7324 "System", "FormatException",
7325 "Invalid character found.");
7326 mono_raise_exception (exc
);
7327 } else if (isspace (c
)) {
7330 prev2_last
= prev_last
;
7336 olength
= ilength
- ignored
;
7338 if (allowWhitespaceOnly
&& olength
== 0) {
7339 return mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, 0);
7342 if ((olength
& 3) != 0 || olength
<= 0) {
7343 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System",
7344 "FormatException", "Invalid length.");
7345 mono_raise_exception (exc
);
7348 if (prev2_last
== '=') {
7349 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7350 mono_raise_exception (exc
);
7353 olength
= (olength
* 3) / 4;
7357 if (prev_last
== '=')
7360 result
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, olength
);
7361 res_ptr
= mono_array_addr (result
, guchar
, 0);
7362 for (i
= 0; i
< ilength
; ) {
7365 for (k
= 0; k
< 4 && i
< ilength
;) {
7371 if (((b
[k
] = dbase64
[c
]) & 0x80) != 0) {
7372 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7373 "System", "FormatException",
7374 "Invalid character found.");
7375 mono_raise_exception (exc
);
7380 *res_ptr
++ = (b
[0] << 2) | (b
[1] >> 4);
7382 *res_ptr
++ = (b
[1] << 4) | (b
[2] >> 2);
7384 *res_ptr
++ = (b
[2] << 6) | b
[3];
7386 while (i
< ilength
&& isspace (start
[i
]))
7394 InternalFromBase64String (MonoString
*str
, MonoBoolean allowWhitespaceOnly
)
7396 MONO_ARCH_SAVE_REGS
;
7398 return base64_to_byte_array (mono_string_chars (str
),
7399 mono_string_length (str
), allowWhitespaceOnly
);
7403 InternalFromBase64CharArray (MonoArray
*input
, gint offset
, gint length
)
7405 MONO_ARCH_SAVE_REGS
;
7407 return base64_to_byte_array (mono_array_addr (input
, gunichar2
, offset
),
7411 #define ICALL_TYPE(id,name,first)
7412 #define ICALL(id,name,func) Icall_ ## id,
7415 #include "metadata/icall-def.h"
7421 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7422 #define ICALL(id,name,func)
7424 #include "metadata/icall-def.h"
7430 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7431 #define ICALL(id,name,func)
7433 guint16 first_icall
;
7436 static const IcallTypeDesc
7437 icall_type_descs
[] = {
7438 #include "metadata/icall-def.h"
7442 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7445 #define ICALL_TYPE(id,name,first)
7448 #ifdef HAVE_ARRAY_ELEM_INIT
7449 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7450 #define MSGSTRFIELD1(line) str##line
7452 static const struct msgstrtn_t
{
7453 #define ICALL(id,name,func)
7455 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7456 #include "metadata/icall-def.h"
7458 } icall_type_names_str
= {
7459 #define ICALL_TYPE(id,name,first) (name),
7460 #include "metadata/icall-def.h"
7463 static const guint16 icall_type_names_idx
[] = {
7464 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7465 #include "metadata/icall-def.h"
7468 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7470 static const struct msgstr_t
{
7472 #define ICALL_TYPE(id,name,first)
7473 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7474 #include "metadata/icall-def.h"
7476 } icall_names_str
= {
7477 #define ICALL(id,name,func) (name),
7478 #include "metadata/icall-def.h"
7481 static const guint16 icall_names_idx
[] = {
7482 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7483 #include "metadata/icall-def.h"
7486 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7492 #define ICALL_TYPE(id,name,first) name,
7493 #define ICALL(id,name,func)
7494 static const char* const
7495 icall_type_names
[] = {
7496 #include "metadata/icall-def.h"
7500 #define icall_type_name_get(id) (icall_type_names [(id)])
7504 #define ICALL_TYPE(id,name,first)
7505 #define ICALL(id,name,func) name,
7506 static const char* const
7508 #include "metadata/icall-def.h"
7511 #define icall_name_get(id) icall_names [(id)]
7513 #endif /* !HAVE_ARRAY_ELEM_INIT */
7517 #define ICALL_TYPE(id,name,first)
7518 #define ICALL(id,name,func) func,
7519 static const gconstpointer
7520 icall_functions
[] = {
7521 #include "metadata/icall-def.h"
7525 static GHashTable
*icall_hash
= NULL
;
7526 static GHashTable
*jit_icall_hash_name
= NULL
;
7527 static GHashTable
*jit_icall_hash_addr
= NULL
;
7530 mono_icall_init (void)
7534 /* check that tables are sorted: disable in release */
7537 const char *prev_class
= NULL
;
7538 const char *prev_method
;
7540 for (i
= 0; i
< Icall_type_num
; ++i
) {
7541 const IcallTypeDesc
*desc
;
7544 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
7545 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
7546 prev_class
= icall_type_name_get (i
);
7547 desc
= &icall_type_descs
[i
];
7548 num_icalls
= icall_desc_num_icalls (desc
);
7549 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7550 for (j
= 0; j
< num_icalls
; ++j
) {
7551 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
7552 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
7553 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
7554 prev_method
= methodn
;
7559 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
7563 mono_icall_cleanup (void)
7565 g_hash_table_destroy (icall_hash
);
7566 g_hash_table_destroy (jit_icall_hash_name
);
7567 g_hash_table_destroy (jit_icall_hash_addr
);
7571 mono_add_internal_call (const char *name
, gconstpointer method
)
7573 mono_loader_lock ();
7575 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
7577 mono_loader_unlock ();
7580 #ifdef HAVE_ARRAY_ELEM_INIT
7582 compare_method_imap (const void *key
, const void *elem
)
7584 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
7585 return strcmp (key
, method_name
);
7589 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7591 const guint16
*nameslot
= bsearch (name
, icall_names_idx
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names_idx
[0]), compare_method_imap
);
7594 return (gpointer
)icall_functions
[(nameslot
- &icall_names_idx
[0])];
7598 compare_class_imap (const void *key
, const void *elem
)
7600 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
7601 return strcmp (key
, class_name
);
7604 static const IcallTypeDesc
*
7605 find_class_icalls (const char *name
)
7607 const guint16
*nameslot
= bsearch (name
, icall_type_names_idx
, Icall_type_num
, sizeof (icall_type_names_idx
[0]), compare_class_imap
);
7610 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
7615 compare_method_imap (const void *key
, const void *elem
)
7617 const char** method_name
= (const char**)elem
;
7618 return strcmp (key
, *method_name
);
7622 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7624 const char **nameslot
= bsearch (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
7627 return (gpointer
)icall_functions
[(nameslot
- icall_names
)];
7631 compare_class_imap (const void *key
, const void *elem
)
7633 const char** class_name
= (const char**)elem
;
7634 return strcmp (key
, *class_name
);
7637 static const IcallTypeDesc
*
7638 find_class_icalls (const char *name
)
7640 const char **nameslot
= bsearch (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
7643 return &icall_type_descs
[nameslot
- icall_type_names
];
7649 * we should probably export this as an helper (handle nested types).
7650 * Returns the number of chars written in buf.
7653 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
7655 int nspacelen
, cnamelen
;
7656 nspacelen
= strlen (klass
->name_space
);
7657 cnamelen
= strlen (klass
->name
);
7658 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
7661 memcpy (buf
, klass
->name_space
, nspacelen
);
7662 buf
[nspacelen
++] = '.';
7664 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
7665 buf
[nspacelen
+ cnamelen
] = 0;
7666 return nspacelen
+ cnamelen
;
7670 mono_lookup_internal_call (MonoMethod
*method
)
7675 int typelen
= 0, mlen
, siglen
;
7677 const IcallTypeDesc
*imap
;
7679 g_assert (method
!= NULL
);
7681 if (method
->is_inflated
)
7682 method
= ((MonoMethodInflated
*) method
)->declaring
;
7684 if (method
->klass
->nested_in
) {
7685 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
7689 mname
[pos
++] = '/';
7692 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
7698 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
7703 imap
= find_class_icalls (mname
);
7705 mname
[typelen
] = ':';
7706 mname
[typelen
+ 1] = ':';
7708 mlen
= strlen (method
->name
);
7709 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
7710 sigstart
= mname
+ typelen
+ 2 + mlen
;
7713 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
7714 siglen
= strlen (tmpsig
);
7715 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
7718 memcpy (sigstart
+ 1, tmpsig
, siglen
);
7719 sigstart
[siglen
+ 1] = ')';
7720 sigstart
[siglen
+ 2] = 0;
7723 mono_loader_lock ();
7725 res
= g_hash_table_lookup (icall_hash
, mname
);
7727 mono_loader_unlock ();
7730 /* try without signature */
7732 res
= g_hash_table_lookup (icall_hash
, mname
);
7734 mono_loader_unlock ();
7738 /* it wasn't found in the static call tables */
7740 mono_loader_unlock ();
7743 res
= find_method_icall (imap
, sigstart
- mlen
);
7745 mono_loader_unlock ();
7748 /* try _with_ signature */
7750 res
= find_method_icall (imap
, sigstart
- mlen
);
7752 mono_loader_unlock ();
7756 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
7757 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7758 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
7759 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7760 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");
7761 g_print ("If you see other errors or faults after this message they are probably related\n");
7762 g_print ("and you need to fix your mono install first.\n");
7764 mono_loader_unlock ();
7770 type_from_typename (char *typename
)
7772 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
7774 if (!strcmp (typename
, "int"))
7775 klass
= mono_defaults
.int_class
;
7776 else if (!strcmp (typename
, "ptr"))
7777 klass
= mono_defaults
.int_class
;
7778 else if (!strcmp (typename
, "void"))
7779 klass
= mono_defaults
.void_class
;
7780 else if (!strcmp (typename
, "int32"))
7781 klass
= mono_defaults
.int32_class
;
7782 else if (!strcmp (typename
, "uint32"))
7783 klass
= mono_defaults
.uint32_class
;
7784 else if (!strcmp (typename
, "int8"))
7785 klass
= mono_defaults
.sbyte_class
;
7786 else if (!strcmp (typename
, "uint8"))
7787 klass
= mono_defaults
.byte_class
;
7788 else if (!strcmp (typename
, "int16"))
7789 klass
= mono_defaults
.int16_class
;
7790 else if (!strcmp (typename
, "uint16"))
7791 klass
= mono_defaults
.uint16_class
;
7792 else if (!strcmp (typename
, "long"))
7793 klass
= mono_defaults
.int64_class
;
7794 else if (!strcmp (typename
, "ulong"))
7795 klass
= mono_defaults
.uint64_class
;
7796 else if (!strcmp (typename
, "float"))
7797 klass
= mono_defaults
.single_class
;
7798 else if (!strcmp (typename
, "double"))
7799 klass
= mono_defaults
.double_class
;
7800 else if (!strcmp (typename
, "object"))
7801 klass
= mono_defaults
.object_class
;
7802 else if (!strcmp (typename
, "obj"))
7803 klass
= mono_defaults
.object_class
;
7804 else if (!strcmp (typename
, "string"))
7805 klass
= mono_defaults
.string_class
;
7806 else if (!strcmp (typename
, "bool"))
7807 klass
= mono_defaults
.boolean_class
;
7808 else if (!strcmp (typename
, "boolean"))
7809 klass
= mono_defaults
.boolean_class
;
7811 g_error ("%s", typename
);
7812 g_assert_not_reached ();
7814 return &klass
->byval_arg
;
7817 MonoMethodSignature
*
7818 mono_create_icall_signature (const char *sigstr
)
7823 MonoMethodSignature
*res
;
7825 mono_loader_lock ();
7826 res
= g_hash_table_lookup (mono_defaults
.corlib
->helper_signatures
, sigstr
);
7828 mono_loader_unlock ();
7832 parts
= g_strsplit (sigstr
, " ", 256);
7841 res
= mono_metadata_signature_alloc (mono_defaults
.corlib
, len
- 1);
7846 * Under windows, the default pinvoke calling convention is STDCALL but
7849 res
->call_convention
= MONO_CALL_C
;
7852 res
->ret
= type_from_typename (parts
[0]);
7853 for (i
= 1; i
< len
; ++i
) {
7854 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
7859 g_hash_table_insert (mono_defaults
.corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
7861 mono_loader_unlock ();
7867 mono_find_jit_icall_by_name (const char *name
)
7869 MonoJitICallInfo
*info
;
7870 g_assert (jit_icall_hash_name
);
7872 mono_loader_lock ();
7873 info
= g_hash_table_lookup (jit_icall_hash_name
, name
);
7874 mono_loader_unlock ();
7879 mono_find_jit_icall_by_addr (gconstpointer addr
)
7881 MonoJitICallInfo
*info
;
7882 g_assert (jit_icall_hash_addr
);
7884 mono_loader_lock ();
7885 info
= g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
7886 mono_loader_unlock ();
7892 * mono_get_jit_icall_info:
7894 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7895 * caller should access it while holding the loader lock.
7898 mono_get_jit_icall_info (void)
7900 return jit_icall_hash_name
;
7904 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
7906 mono_loader_lock ();
7907 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
7908 mono_loader_unlock ();
7912 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
7914 MonoJitICallInfo
*info
;
7919 mono_loader_lock ();
7921 if (!jit_icall_hash_name
) {
7922 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
7923 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
7926 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
7927 g_warning ("jit icall already defined \"%s\"\n", name
);
7928 g_assert_not_reached ();
7931 info
= g_new0 (MonoJitICallInfo
, 1);
7938 info
->wrapper
= func
;
7940 info
->wrapper
= NULL
;
7943 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
7944 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
7946 mono_loader_unlock ();