5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * (C) 2001 Ximian, Inc.
17 #ifdef HAVE_SYS_TIME_H
23 #if defined (PLATFORM_WIN32)
27 #include "mono/utils/mono-membar.h"
28 #include <mono/metadata/object.h>
29 #include <mono/metadata/threads.h>
30 #include <mono/metadata/threads-types.h>
31 #include <mono/metadata/threadpool.h>
32 #include <mono/metadata/monitor.h>
33 #include <mono/metadata/reflection.h>
34 #include <mono/metadata/assembly.h>
35 #include <mono/metadata/tabledefs.h>
36 #include <mono/metadata/exception.h>
37 #include <mono/metadata/file-io.h>
38 #include <mono/metadata/console-io.h>
39 #include <mono/metadata/socket-io.h>
40 #include <mono/metadata/mono-endian.h>
41 #include <mono/metadata/tokentype.h>
42 #include <mono/metadata/domain-internals.h>
43 #include <mono/metadata/metadata-internals.h>
44 #include <mono/metadata/class-internals.h>
45 #include <mono/metadata/marshal.h>
46 #include <mono/metadata/gc-internal.h>
47 #include <mono/metadata/mono-gc.h>
48 #include <mono/metadata/rand.h>
49 #include <mono/metadata/sysmath.h>
50 #include <mono/metadata/string-icalls.h>
51 #include <mono/metadata/debug-helpers.h>
52 #include <mono/metadata/process.h>
53 #include <mono/metadata/environment.h>
54 #include <mono/metadata/profiler-private.h>
55 #include <mono/metadata/locales.h>
56 #include <mono/metadata/filewatcher.h>
57 #include <mono/metadata/char-conversions.h>
58 #include <mono/metadata/security.h>
59 #include <mono/metadata/mono-config.h>
60 #include <mono/metadata/cil-coff.h>
61 #include <mono/metadata/number-formatter.h>
62 #include <mono/metadata/security-manager.h>
63 #include <mono/metadata/security-core-clr.h>
64 #include <mono/metadata/mono-perfcounters.h>
65 #include <mono/metadata/mono-debug.h>
66 #include <mono/io-layer/io-layer.h>
67 #include <mono/utils/strtod.h>
68 #include <mono/utils/monobitset.h>
69 #include <mono/utils/mono-time.h>
70 #include <mono/utils/mono-proclib.h>
72 #if defined (PLATFORM_WIN32)
78 static MonoReflectionAssembly
* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
81 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
);
83 static inline MonoBoolean
84 is_generic_parameter (MonoType
*type
)
86 return !type
->byref
&& (type
->type
== MONO_TYPE_VAR
|| type
->type
== MONO_TYPE_MVAR
);
90 * We expect a pointer to a char, not a string
93 mono_double_ParseImpl (char *ptr
, double *result
)
102 *result
= strtod (ptr
, &endptr
);
105 *result
= mono_strtod (ptr
, &endptr
);
108 if (!*ptr
|| (endptr
&& *endptr
))
115 ves_icall_System_Array_GetValueImpl (MonoObject
*this, guint32 pos
)
124 ao
= (MonoArray
*)this;
125 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
127 esize
= mono_array_element_size (ac
);
128 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
130 if (ac
->element_class
->valuetype
)
131 return mono_value_box (this->vtable
->domain
, ac
->element_class
, ea
);
137 ves_icall_System_Array_GetValue (MonoObject
*this, MonoObject
*idxs
)
145 MONO_CHECK_ARG_NULL (idxs
);
147 io
= (MonoArray
*)idxs
;
148 ic
= (MonoClass
*)io
->obj
.vtable
->klass
;
150 ao
= (MonoArray
*)this;
151 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
153 g_assert (ic
->rank
== 1);
154 if (io
->bounds
!= NULL
|| io
->max_length
!= ac
->rank
)
155 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
157 ind
= (gint32
*)io
->vector
;
159 if (ao
->bounds
== NULL
) {
160 if (*ind
< 0 || *ind
>= ao
->max_length
)
161 mono_raise_exception (mono_get_exception_index_out_of_range ());
163 return ves_icall_System_Array_GetValueImpl (this, *ind
);
166 for (i
= 0; i
< ac
->rank
; i
++)
167 if ((ind
[i
] < ao
->bounds
[i
].lower_bound
) ||
168 (ind
[i
] >= ao
->bounds
[i
].length
+ ao
->bounds
[i
].lower_bound
))
169 mono_raise_exception (mono_get_exception_index_out_of_range ());
171 pos
= ind
[0] - ao
->bounds
[0].lower_bound
;
172 for (i
= 1; i
< ac
->rank
; i
++)
173 pos
= pos
*ao
->bounds
[i
].length
+ ind
[i
] -
174 ao
->bounds
[i
].lower_bound
;
176 return ves_icall_System_Array_GetValueImpl (this, pos
);
180 ves_icall_System_Array_SetValueImpl (MonoArray
*this, MonoObject
*value
, guint32 pos
)
182 MonoClass
*ac
, *vc
, *ec
;
194 vc
= value
->vtable
->klass
;
198 ac
= this->obj
.vtable
->klass
;
199 ec
= ac
->element_class
;
201 esize
= mono_array_element_size (ac
);
202 ea
= (gpointer
*)((char*)this->vector
+ (pos
* esize
));
203 va
= (gpointer
*)((char*)value
+ sizeof (MonoObject
));
206 memset (ea
, 0, esize
);
210 #define NO_WIDENING_CONVERSION G_STMT_START{\
211 mono_raise_exception (mono_get_exception_argument ( \
212 "value", "not a widening conversion")); \
215 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
216 if (esize < vsize + (extra)) \
217 mono_raise_exception (mono_get_exception_argument ( \
218 "value", "not a widening conversion")); \
221 #define INVALID_CAST G_STMT_START{\
222 mono_raise_exception (mono_get_exception_invalid_cast ()); \
225 /* Check element (destination) type. */
226 switch (ec
->byval_arg
.type
) {
227 case MONO_TYPE_STRING
:
228 switch (vc
->byval_arg
.type
) {
229 case MONO_TYPE_STRING
:
235 case MONO_TYPE_BOOLEAN
:
236 switch (vc
->byval_arg
.type
) {
237 case MONO_TYPE_BOOLEAN
:
250 NO_WIDENING_CONVERSION
;
257 if (!ec
->valuetype
) {
258 if (!mono_object_isinst (value
, ec
))
260 mono_gc_wbarrier_set_arrayref (this, ea
, (MonoObject
*)value
);
264 if (mono_object_isinst (value
, ec
)) {
265 if (ec
->has_references
)
266 mono_value_copy (ea
, (char*)value
+ sizeof (MonoObject
), ec
);
268 memcpy (ea
, (char *)value
+ sizeof (MonoObject
), esize
);
275 vsize
= mono_class_instance_size (vc
) - sizeof (MonoObject
);
277 et
= ec
->byval_arg
.type
;
278 if (et
== MONO_TYPE_VALUETYPE
&& ec
->byval_arg
.data
.klass
->enumtype
)
279 et
= ec
->byval_arg
.data
.klass
->enum_basetype
->type
;
281 vt
= vc
->byval_arg
.type
;
282 if (vt
== MONO_TYPE_VALUETYPE
&& vc
->byval_arg
.data
.klass
->enumtype
)
283 vt
= vc
->byval_arg
.data
.klass
->enum_basetype
->type
;
285 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
291 case MONO_TYPE_CHAR: \
292 CHECK_WIDENING_CONVERSION(0); \
293 *(etype *) ea = (etype) u64; \
295 /* You can't assign a signed value to an unsigned array. */ \
300 /* You can't assign a floating point number to an integer array. */ \
303 NO_WIDENING_CONVERSION; \
307 #define ASSIGN_SIGNED(etype) G_STMT_START{\
313 CHECK_WIDENING_CONVERSION(0); \
314 *(etype *) ea = (etype) i64; \
316 /* You can assign an unsigned value to a signed array if the array's */ \
317 /* element size is larger than the value size. */ \
322 case MONO_TYPE_CHAR: \
323 CHECK_WIDENING_CONVERSION(1); \
324 *(etype *) ea = (etype) u64; \
326 /* You can't assign a floating point number to an integer array. */ \
329 NO_WIDENING_CONVERSION; \
333 #define ASSIGN_REAL(etype) G_STMT_START{\
337 CHECK_WIDENING_CONVERSION(0); \
338 *(etype *) ea = (etype) r64; \
340 /* All integer values fit into a floating point array, so we don't */ \
341 /* need to CHECK_WIDENING_CONVERSION here. */ \
346 *(etype *) ea = (etype) i64; \
352 case MONO_TYPE_CHAR: \
353 *(etype *) ea = (etype) u64; \
360 u64
= *(guint8
*) va
;
363 u64
= *(guint16
*) va
;
366 u64
= *(guint32
*) va
;
369 u64
= *(guint64
*) va
;
375 i64
= *(gint16
*) va
;
378 i64
= *(gint32
*) va
;
381 i64
= *(gint64
*) va
;
384 r64
= *(gfloat
*) va
;
387 r64
= *(gdouble
*) va
;
390 u64
= *(guint16
*) va
;
392 case MONO_TYPE_BOOLEAN
:
393 /* Boolean is only compatible with itself. */
406 NO_WIDENING_CONVERSION
;
413 /* If we can't do a direct copy, let's try a widening conversion. */
416 ASSIGN_UNSIGNED (guint16
);
418 ASSIGN_UNSIGNED (guint8
);
420 ASSIGN_UNSIGNED (guint16
);
422 ASSIGN_UNSIGNED (guint32
);
424 ASSIGN_UNSIGNED (guint64
);
426 ASSIGN_SIGNED (gint8
);
428 ASSIGN_SIGNED (gint16
);
430 ASSIGN_SIGNED (gint32
);
432 ASSIGN_SIGNED (gint64
);
434 ASSIGN_REAL (gfloat
);
436 ASSIGN_REAL (gdouble
);
440 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
444 #undef NO_WIDENING_CONVERSION
445 #undef CHECK_WIDENING_CONVERSION
446 #undef ASSIGN_UNSIGNED
452 ves_icall_System_Array_SetValue (MonoArray
*this, MonoObject
*value
,
460 MONO_CHECK_ARG_NULL (idxs
);
462 ic
= idxs
->obj
.vtable
->klass
;
463 ac
= this->obj
.vtable
->klass
;
465 g_assert (ic
->rank
== 1);
466 if (idxs
->bounds
!= NULL
|| idxs
->max_length
!= ac
->rank
)
467 mono_raise_exception (mono_get_exception_argument (NULL
, NULL
));
469 ind
= (gint32
*)idxs
->vector
;
471 if (this->bounds
== NULL
) {
472 if (*ind
< 0 || *ind
>= this->max_length
)
473 mono_raise_exception (mono_get_exception_index_out_of_range ());
475 ves_icall_System_Array_SetValueImpl (this, value
, *ind
);
479 for (i
= 0; i
< ac
->rank
; i
++)
480 if ((ind
[i
] < this->bounds
[i
].lower_bound
) ||
481 (ind
[i
] >= this->bounds
[i
].length
+ this->bounds
[i
].lower_bound
))
482 mono_raise_exception (mono_get_exception_index_out_of_range ());
484 pos
= ind
[0] - this->bounds
[0].lower_bound
;
485 for (i
= 1; i
< ac
->rank
; i
++)
486 pos
= pos
* this->bounds
[i
].length
+ ind
[i
] -
487 this->bounds
[i
].lower_bound
;
489 ves_icall_System_Array_SetValueImpl (this, value
, pos
);
493 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
497 mono_array_size_t
*sizes
, i
;
498 gboolean bounded
= FALSE
;
502 MONO_CHECK_ARG_NULL (type
);
503 MONO_CHECK_ARG_NULL (lengths
);
505 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
507 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
509 for (i
= 0; i
< mono_array_length (lengths
); i
++)
510 if (mono_array_get (lengths
, gint32
, i
) < 0)
511 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
513 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint32
, 0) != 0))
514 /* vectors are not the same as one dimensional arrays with no-zero bounds */
519 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
521 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
522 for (i
= 0; i
< aklass
->rank
; ++i
) {
523 sizes
[i
] = mono_array_get (lengths
, guint32
, i
);
525 sizes
[i
+ aklass
->rank
] = mono_array_get (bounds
, guint32
, i
);
527 sizes
[i
+ aklass
->rank
] = 0;
530 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
536 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType
*type
, MonoArray
*lengths
, MonoArray
*bounds
)
540 mono_array_size_t
*sizes
, i
;
541 gboolean bounded
= FALSE
;
545 MONO_CHECK_ARG_NULL (type
);
546 MONO_CHECK_ARG_NULL (lengths
);
548 MONO_CHECK_ARG (lengths
, mono_array_length (lengths
) > 0);
550 MONO_CHECK_ARG (bounds
, mono_array_length (lengths
) == mono_array_length (bounds
));
552 for (i
= 0; i
< mono_array_length (lengths
); i
++)
553 if ((mono_array_get (lengths
, gint64
, i
) < 0) ||
554 (mono_array_get (lengths
, gint64
, i
) > MONO_ARRAY_MAX_INDEX
))
555 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL
));
557 if (bounds
&& (mono_array_length (bounds
) == 1) && (mono_array_get (bounds
, gint64
, 0) != 0))
558 /* vectors are not the same as one dimensional arrays with no-zero bounds */
563 aklass
= mono_bounded_array_class_get (mono_class_from_mono_type (type
->type
), mono_array_length (lengths
), bounded
);
565 sizes
= alloca (aklass
->rank
* sizeof(mono_array_size_t
) * 2);
566 for (i
= 0; i
< aklass
->rank
; ++i
) {
567 sizes
[i
] = mono_array_get (lengths
, guint64
, i
);
569 sizes
[i
+ aklass
->rank
] = (mono_array_size_t
) mono_array_get (bounds
, guint64
, i
);
571 sizes
[i
+ aklass
->rank
] = 0;
574 array
= mono_array_new_full (mono_object_domain (type
), aklass
, sizes
, sizes
+ aklass
->rank
);
580 ves_icall_System_Array_GetRank (MonoObject
*this)
584 return this->vtable
->klass
->rank
;
588 ves_icall_System_Array_GetLength (MonoArray
*this, gint32 dimension
)
590 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
591 mono_array_size_t length
;
595 if ((dimension
< 0) || (dimension
>= rank
))
596 mono_raise_exception (mono_get_exception_index_out_of_range ());
598 if (this->bounds
== NULL
)
599 length
= this->max_length
;
601 length
= this->bounds
[dimension
].length
;
603 #ifdef MONO_BIG_ARRAYS
604 if (length
> G_MAXINT32
)
605 mono_raise_exception (mono_get_exception_overflow ());
611 ves_icall_System_Array_GetLongLength (MonoArray
*this, gint32 dimension
)
613 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
617 if ((dimension
< 0) || (dimension
>= rank
))
618 mono_raise_exception (mono_get_exception_index_out_of_range ());
620 if (this->bounds
== NULL
)
621 return this->max_length
;
623 return this->bounds
[dimension
].length
;
627 ves_icall_System_Array_GetLowerBound (MonoArray
*this, gint32 dimension
)
629 gint32 rank
= ((MonoObject
*)this)->vtable
->klass
->rank
;
633 if ((dimension
< 0) || (dimension
>= rank
))
634 mono_raise_exception (mono_get_exception_index_out_of_range ());
636 if (this->bounds
== NULL
)
639 return this->bounds
[dimension
].lower_bound
;
643 ves_icall_System_Array_ClearInternal (MonoArray
*arr
, int idx
, int length
)
645 int sz
= mono_array_element_size (mono_object_class (arr
));
646 memset (mono_array_addr_with_size (arr
, sz
, idx
), 0, length
* sz
);
650 ves_icall_System_Array_FastCopy (MonoArray
*source
, int source_idx
, MonoArray
* dest
, int dest_idx
, int length
)
655 MonoClass
*src_class
;
656 MonoClass
*dest_class
;
661 if (source
->obj
.vtable
->klass
->rank
!= dest
->obj
.vtable
->klass
->rank
)
664 if (source
->bounds
|| dest
->bounds
)
667 if ((dest_idx
+ length
> mono_array_length (dest
)) ||
668 (source_idx
+ length
> mono_array_length (source
)))
671 src_class
= source
->obj
.vtable
->klass
->element_class
;
672 dest_class
= dest
->obj
.vtable
->klass
->element_class
;
675 * Handle common cases.
678 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
679 if (src_class
== mono_defaults
.object_class
&& dest_class
->valuetype
) {
680 int has_refs
= dest_class
->has_references
;
681 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
682 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
683 if (elem
&& !mono_object_isinst (elem
, dest_class
))
687 element_size
= mono_array_element_size (dest
->obj
.vtable
->klass
);
688 memset (mono_array_addr_with_size (dest
, element_size
, dest_idx
), 0, element_size
* length
);
689 for (i
= 0; i
< length
; ++i
) {
690 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, source_idx
+ i
);
691 void *addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
+ i
);
695 mono_value_copy (addr
, (char *)elem
+ sizeof (MonoObject
), dest_class
);
697 memcpy (addr
, (char *)elem
+ sizeof (MonoObject
), element_size
);
702 /* Check if we're copying a char[] <==> (u)short[] */
703 if (src_class
!= dest_class
) {
704 if (dest_class
->valuetype
|| dest_class
->enumtype
|| src_class
->valuetype
|| src_class
->enumtype
)
707 if (mono_class_is_subclass_of (src_class
, dest_class
, FALSE
))
709 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
710 else if (mono_class_is_subclass_of (dest_class
, src_class
, FALSE
))
711 for (i
= source_idx
; i
< source_idx
+ length
; ++i
) {
712 MonoObject
*elem
= mono_array_get (source
, MonoObject
*, i
);
713 if (elem
&& !mono_object_isinst (elem
, dest_class
))
720 if (dest_class
->valuetype
) {
721 element_size
= mono_array_element_size (source
->obj
.vtable
->klass
);
722 source_addr
= mono_array_addr_with_size (source
, element_size
, source_idx
);
723 if (dest_class
->has_references
) {
724 mono_value_copy_array (dest
, dest_idx
, source_addr
, length
);
726 dest_addr
= mono_array_addr_with_size (dest
, element_size
, dest_idx
);
727 memmove (dest_addr
, source_addr
, element_size
* length
);
730 mono_array_memcpy_refs (dest
, dest_idx
, source
, source_idx
, length
);
737 ves_icall_System_Array_GetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
746 ao
= (MonoArray
*)this;
747 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
749 esize
= mono_array_element_size (ac
);
750 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
752 memcpy (value
, ea
, esize
);
756 ves_icall_System_Array_SetGenericValueImpl (MonoObject
*this, guint32 pos
, gpointer value
)
765 ao
= (MonoArray
*)this;
766 ac
= (MonoClass
*)ao
->obj
.vtable
->klass
;
768 esize
= mono_array_element_size (ac
);
769 ea
= (gpointer
*)((char*)ao
->vector
+ (pos
* esize
));
771 memcpy (ea
, value
, esize
);
775 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray
*array
, MonoClassField
*field_handle
)
777 MonoClass
*klass
= array
->obj
.vtable
->klass
;
778 guint32 size
= mono_array_element_size (klass
);
779 MonoType
*type
= mono_type_get_underlying_type (&klass
->element_class
->byval_arg
);
781 const char *field_data
;
783 if (MONO_TYPE_IS_REFERENCE (type
) ||
784 (type
->type
== MONO_TYPE_VALUETYPE
&&
785 (!mono_type_get_class (type
) ||
786 mono_type_get_class (type
)->has_references
))) {
787 MonoException
*exc
= mono_get_exception_argument("array",
788 "Cannot initialize array containing references");
789 mono_raise_exception (exc
);
792 if (!(field_handle
->type
->attrs
& FIELD_ATTRIBUTE_HAS_FIELD_RVA
)) {
793 MonoException
*exc
= mono_get_exception_argument("field_handle",
794 "Field doesn't have an RVA");
795 mono_raise_exception (exc
);
798 size
*= array
->max_length
;
799 field_data
= mono_field_get_data (field_handle
);
801 if (size
> mono_type_size (field_handle
->type
, &align
)) {
802 MonoException
*exc
= mono_get_exception_argument("field_handle",
803 "Field not large enough to fill array");
804 mono_raise_exception (exc
);
807 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
809 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
810 guint ## n *src = (guint ## n *) field_data; \
811 guint ## n *end = (guint ## n *)((char*)src + size); \
813 for (; src < end; data++, src++) { \
814 *data = read ## n (src); \
818 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
820 switch (type
->type
) {
837 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
841 memcpy (mono_array_addr (array
, char, 0), field_data
, size
);
843 if (klass
->element_class
->byval_arg
.type
== MONO_TYPE_R8
) {
846 double *data
= (double*)mono_array_addr (array
, double, 0);
848 for (i
= 0; i
< size
; i
++, data
++) {
858 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
862 return offsetof (MonoString
, chars
);
866 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject
*obj
)
870 if ((obj
== NULL
) || (! (obj
->vtable
->klass
->valuetype
)))
873 return mono_object_clone (obj
);
877 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType
*handle
)
883 MONO_CHECK_ARG_NULL (handle
);
885 klass
= mono_class_from_mono_type (handle
);
886 MONO_CHECK_ARG (handle
, klass
);
888 /* This will call the type constructor */
889 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass
));
893 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage
*image
)
897 mono_image_check_for_module_cctor (image
);
898 if (image
->has_module_cctor
) {
899 MonoClass
*module_klass
= mono_class_get (image
, MONO_TOKEN_TYPE_DEF
| 1);
900 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass
));
905 ves_icall_System_Object_MemberwiseClone (MonoObject
*this)
909 return mono_object_clone (this);
913 ves_icall_System_ValueType_InternalGetHashCode (MonoObject
*this, MonoArray
**fields
)
916 MonoObject
**values
= NULL
;
920 MonoClassField
* field
;
925 klass
= mono_object_class (this);
927 if (mono_class_num_fields (klass
) == 0)
928 return mono_object_hash (this);
931 * Compute the starting value of the hashcode for fields of primitive
932 * types, and return the remaining fields in an array to the managed side.
933 * This way, we can avoid costly reflection operations in managed code.
936 while ((field
= mono_class_get_fields (klass
, &iter
))) {
937 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
939 if (mono_field_is_deleted (field
))
941 /* FIXME: Add more types */
942 switch (field
->type
->type
) {
944 result
^= *(gint32
*)((guint8
*)this + field
->offset
);
946 case MONO_TYPE_STRING
: {
948 s
= *(MonoString
**)((guint8
*)this + field
->offset
);
950 result
^= mono_string_hash (s
);
955 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
));
956 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
957 values
[count
++] = o
;
963 *fields
= mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
);
964 for (i
= 0; i
< count
; ++i
)
965 mono_array_setref (*fields
, i
, values
[i
]);
973 ves_icall_System_ValueType_Equals (MonoObject
*this, MonoObject
*that
, MonoArray
**fields
)
976 MonoObject
**values
= NULL
;
978 MonoClassField
* field
;
984 MONO_CHECK_ARG_NULL (that
);
986 if (this->vtable
!= that
->vtable
)
989 klass
= mono_object_class (this);
991 if (klass
->enumtype
&& klass
->enum_basetype
&& klass
->enum_basetype
->type
== MONO_TYPE_I4
)
992 return (*(gint32
*)((guint8
*)this + sizeof (MonoObject
)) == *(gint32
*)((guint8
*)that
+ sizeof (MonoObject
)));
995 * Do the comparison for fields of primitive type and return a result if
996 * possible. Otherwise, return the remaining fields in an array to the
997 * managed side. This way, we can avoid costly reflection operations in
1002 while ((field
= mono_class_get_fields (klass
, &iter
))) {
1003 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1005 if (mono_field_is_deleted (field
))
1007 /* FIXME: Add more types */
1008 switch (field
->type
->type
) {
1011 case MONO_TYPE_BOOLEAN
:
1012 if (*((guint8
*)this + field
->offset
) != *((guint8
*)that
+ field
->offset
))
1017 case MONO_TYPE_CHAR
:
1018 if (*(gint16
*)((guint8
*)this + field
->offset
) != *(gint16
*)((guint8
*)that
+ field
->offset
))
1023 if (*(gint32
*)((guint8
*)this + field
->offset
) != *(gint32
*)((guint8
*)that
+ field
->offset
))
1028 if (*(gint64
*)((guint8
*)this + field
->offset
) != *(gint64
*)((guint8
*)that
+ field
->offset
))
1032 if (*(float*)((guint8
*)this + field
->offset
) != *(float*)((guint8
*)that
+ field
->offset
))
1036 if (*(double*)((guint8
*)this + field
->offset
) != *(double*)((guint8
*)that
+ field
->offset
))
1041 case MONO_TYPE_STRING
: {
1042 MonoString
*s1
, *s2
;
1043 guint32 s1len
, s2len
;
1044 s1
= *(MonoString
**)((guint8
*)this + field
->offset
);
1045 s2
= *(MonoString
**)((guint8
*)that
+ field
->offset
);
1048 if ((s1
== NULL
) || (s2
== NULL
))
1050 s1len
= mono_string_length (s1
);
1051 s2len
= mono_string_length (s2
);
1055 if (memcmp (mono_string_chars (s1
), mono_string_chars (s2
), s1len
* sizeof (gunichar2
)) != 0)
1061 values
= g_newa (MonoObject
*, mono_class_num_fields (klass
) * 2);
1062 o
= mono_field_get_value_object (mono_object_domain (this), field
, this);
1063 values
[count
++] = o
;
1064 o
= mono_field_get_value_object (mono_object_domain (this), field
, that
);
1065 values
[count
++] = o
;
1068 if (klass
->enumtype
)
1069 /* enums only have one non-static field */
1075 *fields
= mono_array_new (mono_domain_get (), mono_defaults
.object_class
, count
);
1076 for (i
= 0; i
< count
; ++i
)
1077 mono_array_setref (*fields
, i
, values
[i
]);
1084 static MonoReflectionType
*
1085 ves_icall_System_Object_GetType (MonoObject
*obj
)
1087 MONO_ARCH_SAVE_REGS
;
1089 if (obj
->vtable
->klass
!= mono_defaults
.transparent_proxy_class
)
1090 return mono_type_get_object (mono_object_domain (obj
), &obj
->vtable
->klass
->byval_arg
);
1092 return mono_type_get_object (mono_object_domain (obj
), &((MonoTransparentProxy
*)obj
)->remote_class
->proxy_class
->byval_arg
);
1096 mono_type_type_from_obj (MonoReflectionType
*mtype
, MonoObject
*obj
)
1098 MONO_ARCH_SAVE_REGS
;
1100 mtype
->type
= &obj
->vtable
->klass
->byval_arg
;
1101 g_assert (mtype
->type
->type
);
1105 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
)
1107 MONO_ARCH_SAVE_REGS
;
1109 MONO_CHECK_ARG_NULL (obj
);
1111 return mono_image_create_token (mb
->dynamic_image
, obj
, TRUE
, TRUE
);
1115 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder
*mb
,
1116 MonoReflectionMethod
*method
,
1117 MonoArray
*opt_param_types
)
1119 MONO_ARCH_SAVE_REGS
;
1121 MONO_CHECK_ARG_NULL (method
);
1123 return mono_image_create_method_token (
1124 mb
->dynamic_image
, (MonoObject
*) method
, opt_param_types
);
1128 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder
*mb
, HANDLE file
)
1130 MONO_ARCH_SAVE_REGS
;
1132 mono_image_create_pefile (mb
, file
);
1136 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder
*mb
)
1138 MONO_ARCH_SAVE_REGS
;
1140 mono_image_build_metadata (mb
);
1144 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder
*mb
, MonoObject
*obj
, guint32 token
)
1146 MONO_ARCH_SAVE_REGS
;
1148 mono_image_register_token (mb
->dynamic_image
, token
, obj
);
1152 get_caller (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1154 MonoMethod
**dest
= data
;
1156 /* skip unmanaged frames */
1172 get_executing (MonoMethod
*m
, gint32 no
, gint32 ilo
, gboolean managed
, gpointer data
)
1174 MonoMethod
**dest
= data
;
1176 /* skip unmanaged frames */
1181 if (!strcmp (m
->klass
->name_space
, "System.Reflection"))
1189 static MonoReflectionType
*
1190 type_from_name (const char *str
, MonoBoolean ignoreCase
)
1192 MonoType
*type
= NULL
;
1193 MonoAssembly
*assembly
= NULL
;
1194 MonoTypeNameParse info
;
1195 char *temp_str
= g_strdup (str
);
1196 gboolean type_resolve
= FALSE
;
1198 MONO_ARCH_SAVE_REGS
;
1200 /* mono_reflection_parse_type() mangles the string */
1201 if (!mono_reflection_parse_type (temp_str
, &info
)) {
1202 mono_reflection_free_type_info (&info
);
1207 if (info
.assembly
.name
) {
1208 assembly
= mono_assembly_load (&info
.assembly
, NULL
, NULL
);
1210 MonoMethod
*m
= mono_method_get_last_managed ();
1211 MonoMethod
*dest
= m
;
1213 mono_stack_walk_no_il (get_caller
, &dest
);
1218 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1219 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1220 * to crash. This only seems to happen in some strange remoting
1221 * scenarios and I was unable to figure out what's happening there.
1222 * Dec 10, 2005 - Martin.
1226 assembly
= dest
->klass
->image
->assembly
;
1228 g_warning (G_STRLOC
);
1233 type
= mono_reflection_get_type (assembly
->image
, &info
, ignoreCase
, &type_resolve
);
1235 if (!info
.assembly
.name
&& !type
) /* try mscorlib */
1236 type
= mono_reflection_get_type (NULL
, &info
, ignoreCase
, &type_resolve
);
1238 mono_reflection_free_type_info (&info
);
1244 return mono_type_get_object (mono_domain_get (), type
);
1248 MonoReflectionType
*
1249 mono_type_get (const char *str
)
1251 char *copy
= g_strdup (str
);
1252 MonoReflectionType
*type
= type_from_name (copy
, FALSE
);
1259 static MonoReflectionType
*
1260 ves_icall_type_from_name (MonoString
*name
,
1261 MonoBoolean throwOnError
,
1262 MonoBoolean ignoreCase
)
1264 char *str
= mono_string_to_utf8 (name
);
1265 MonoReflectionType
*type
;
1267 type
= type_from_name (str
, ignoreCase
);
1270 MonoException
*e
= NULL
;
1273 e
= mono_get_exception_type_load (name
, NULL
);
1275 mono_loader_clear_error ();
1277 mono_raise_exception (e
);
1284 static MonoReflectionType
*
1285 ves_icall_type_from_handle (MonoType
*handle
)
1287 MonoDomain
*domain
= mono_domain_get ();
1288 MonoClass
*klass
= mono_class_from_mono_type (handle
);
1290 MONO_ARCH_SAVE_REGS
;
1292 mono_class_init (klass
);
1293 return mono_type_get_object (domain
, handle
);
1297 ves_icall_System_Type_EqualsInternal (MonoReflectionType
*type
, MonoReflectionType
*c
)
1299 MONO_ARCH_SAVE_REGS
;
1301 if (c
&& type
->type
&& c
->type
)
1302 return mono_metadata_type_equal (type
->type
, c
->type
);
1307 /* System.TypeCode */
1326 TYPECODE_STRING
= 18
1330 ves_icall_type_GetTypeCodeInternal (MonoReflectionType
*type
)
1332 int t
= type
->type
->type
;
1334 MONO_ARCH_SAVE_REGS
;
1336 if (type
->type
->byref
)
1337 return TYPECODE_OBJECT
;
1341 case MONO_TYPE_VOID
:
1342 return TYPECODE_OBJECT
;
1343 case MONO_TYPE_BOOLEAN
:
1344 return TYPECODE_BOOLEAN
;
1346 return TYPECODE_BYTE
;
1348 return TYPECODE_SBYTE
;
1350 return TYPECODE_UINT16
;
1352 return TYPECODE_INT16
;
1353 case MONO_TYPE_CHAR
:
1354 return TYPECODE_CHAR
;
1358 return TYPECODE_OBJECT
;
1360 return TYPECODE_UINT32
;
1362 return TYPECODE_INT32
;
1364 return TYPECODE_UINT64
;
1366 return TYPECODE_INT64
;
1368 return TYPECODE_SINGLE
;
1370 return TYPECODE_DOUBLE
;
1371 case MONO_TYPE_VALUETYPE
:
1372 if (type
->type
->data
.klass
->enumtype
) {
1373 t
= type
->type
->data
.klass
->enum_basetype
->type
;
1376 MonoClass
*k
= type
->type
->data
.klass
;
1377 if (strcmp (k
->name_space
, "System") == 0) {
1378 if (strcmp (k
->name
, "Decimal") == 0)
1379 return TYPECODE_DECIMAL
;
1380 else if (strcmp (k
->name
, "DateTime") == 0)
1381 return TYPECODE_DATETIME
;
1384 return TYPECODE_OBJECT
;
1385 case MONO_TYPE_STRING
:
1386 return TYPECODE_STRING
;
1387 case MONO_TYPE_SZARRAY
:
1388 case MONO_TYPE_ARRAY
:
1389 case MONO_TYPE_OBJECT
:
1391 case MONO_TYPE_MVAR
:
1392 case MONO_TYPE_TYPEDBYREF
:
1393 return TYPECODE_OBJECT
;
1394 case MONO_TYPE_CLASS
:
1396 MonoClass
*k
= type
->type
->data
.klass
;
1397 if (strcmp (k
->name_space
, "System") == 0) {
1398 if (strcmp (k
->name
, "DBNull") == 0)
1399 return TYPECODE_DBNULL
;
1402 return TYPECODE_OBJECT
;
1403 case MONO_TYPE_GENERICINST
:
1404 return TYPECODE_OBJECT
;
1406 g_error ("type 0x%02x not handled in GetTypeCode()", t
);
1412 ves_icall_type_is_subtype_of (MonoReflectionType
*type
, MonoReflectionType
*c
, MonoBoolean check_interfaces
)
1418 MONO_ARCH_SAVE_REGS
;
1420 g_assert (type
!= NULL
);
1422 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1424 if (!c
) /* FIXME: dont know what do do here */
1427 klass
= mono_class_from_mono_type (type
->type
);
1428 klassc
= mono_class_from_mono_type (c
->type
);
1430 if (type
->type
->byref
)
1431 return klassc
== mono_defaults
.object_class
;
1433 return mono_class_is_subclass_of (klass
, klassc
, check_interfaces
);
1437 ves_icall_type_is_assignable_from (MonoReflectionType
*type
, MonoReflectionType
*c
)
1443 MONO_ARCH_SAVE_REGS
;
1445 g_assert (type
!= NULL
);
1447 domain
= ((MonoObject
*)type
)->vtable
->domain
;
1449 klass
= mono_class_from_mono_type (type
->type
);
1450 klassc
= mono_class_from_mono_type (c
->type
);
1452 if (type
->type
->byref
&& !c
->type
->byref
)
1455 return mono_class_is_assignable_from (klass
, klassc
);
1459 ves_icall_type_IsInstanceOfType (MonoReflectionType
*type
, MonoObject
*obj
)
1461 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1462 return mono_object_isinst (obj
, klass
) != NULL
;
1466 ves_icall_get_attributes (MonoReflectionType
*type
)
1468 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
1470 MONO_ARCH_SAVE_REGS
;
1472 return klass
->flags
;
1475 static MonoReflectionMarshal
*
1476 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField
*field
)
1478 MonoClass
*klass
= field
->field
->parent
;
1479 MonoMarshalType
*info
;
1482 if (klass
->generic_container
||
1483 (klass
->generic_class
&& klass
->generic_class
->context
.class_inst
->is_open
))
1486 info
= mono_marshal_load_type_info (klass
);
1488 for (i
= 0; i
< info
->num_fields
; ++i
) {
1489 if (info
->fields
[i
].field
== field
->field
) {
1490 if (!info
->fields
[i
].mspec
)
1493 return mono_reflection_marshal_from_marshal_spec (field
->object
.vtable
->domain
, klass
, info
->fields
[i
].mspec
);
1500 static MonoReflectionField
*
1501 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField
*handle
, MonoClass
*klass
)
1506 klass
= handle
->parent
;
1508 /* FIXME: check that handle is a field of klass or of a parent: return null
1509 * and throw the exception in managed code.
1511 return mono_field_get_object (mono_domain_get (), klass
, handle
);
1514 static MonoReflectionField
*
1515 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField
*handle
)
1517 MONO_ARCH_SAVE_REGS
;
1521 return mono_field_get_object (mono_domain_get (), handle
->parent
, handle
);
1525 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField
*field
, MonoBoolean optional
)
1527 MonoType
*type
= field
->field
->type
;
1529 return type_array_from_modifiers (field
->field
->parent
->image
, type
, optional
);
1533 ves_icall_get_method_info (MonoMethod
*method
, MonoMethodInfo
*info
)
1535 MonoDomain
*domain
= mono_domain_get ();
1536 MonoMethodSignature
* sig
;
1537 MONO_ARCH_SAVE_REGS
;
1539 sig
= mono_method_signature (method
);
1541 g_assert (mono_loader_get_last_error ());
1542 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1545 info
->parent
= mono_type_get_object (domain
, &method
->klass
->byval_arg
);
1546 info
->ret
= mono_type_get_object (domain
, sig
->ret
);
1547 info
->attrs
= method
->flags
;
1548 info
->implattrs
= method
->iflags
;
1549 if (sig
->call_convention
== MONO_CALL_DEFAULT
)
1550 info
->callconv
= sig
->sentinelpos
>= 0 ? 2 : 1;
1552 if (sig
->call_convention
== MONO_CALL_VARARG
|| sig
->sentinelpos
>= 0)
1557 info
->callconv
|= (sig
->hasthis
<< 5) | (sig
->explicit_this
<< 6);
1561 ves_icall_get_parameter_info (MonoMethod
*method
)
1563 MonoDomain
*domain
= mono_domain_get ();
1565 return mono_param_get_objects (domain
, method
);
1568 static MonoReflectionMarshal
*
1569 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod
*method
)
1571 MonoDomain
*domain
= mono_domain_get ();
1572 MonoReflectionMarshal
* res
= NULL
;
1573 MonoMarshalSpec
**mspecs
;
1576 mspecs
= g_new (MonoMarshalSpec
*, mono_method_signature (method
)->param_count
+ 1);
1577 mono_method_get_marshal_info (method
, mspecs
);
1580 res
= mono_reflection_marshal_from_marshal_spec (domain
, method
->klass
, mspecs
[0]);
1582 for (i
= mono_method_signature (method
)->param_count
; i
>= 0; i
--)
1584 mono_metadata_free_marshal_spec (mspecs
[i
]);
1591 ves_icall_MonoField_GetFieldOffset (MonoReflectionField
*field
)
1593 return field
->field
->offset
- sizeof (MonoObject
);
1596 static MonoReflectionType
*
1597 ves_icall_MonoField_GetParentType (MonoReflectionField
*field
, MonoBoolean declaring
)
1600 MONO_ARCH_SAVE_REGS
;
1602 parent
= declaring
? field
->field
->parent
: field
->klass
;
1604 return mono_type_get_object (mono_object_domain (field
), &parent
->byval_arg
);
1608 ves_icall_MonoField_GetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
)
1611 MonoClassField
*cf
= field
->field
;
1615 MonoDomain
*domain
= mono_object_domain (field
);
1617 gboolean is_static
= FALSE
;
1618 gboolean is_ref
= FALSE
;
1620 MONO_ARCH_SAVE_REGS
;
1622 if (field
->klass
->image
->assembly
->ref_only
)
1623 mono_raise_exception (mono_get_exception_invalid_operation (
1624 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1626 mono_class_init (field
->klass
);
1628 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
)
1631 if (obj
&& !is_static
) {
1632 /* Check that the field belongs to the object */
1633 gboolean found
= FALSE
;
1636 for (k
= obj
->vtable
->klass
; k
; k
= k
->parent
) {
1637 if (k
== cf
->parent
) {
1644 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
);
1645 MonoException
*ex
= mono_get_exception_argument (NULL
, msg
);
1647 mono_raise_exception (ex
);
1651 t
= mono_type_get_underlying_type (cf
->type
);
1653 case MONO_TYPE_STRING
:
1654 case MONO_TYPE_OBJECT
:
1655 case MONO_TYPE_CLASS
:
1656 case MONO_TYPE_ARRAY
:
1657 case MONO_TYPE_SZARRAY
:
1662 case MONO_TYPE_BOOLEAN
:
1665 case MONO_TYPE_CHAR
:
1674 case MONO_TYPE_VALUETYPE
:
1677 case MONO_TYPE_GENERICINST
:
1678 if (mono_type_generic_inst_is_valuetype (t
)) {
1685 g_error ("type 0x%x not handled in "
1686 "ves_icall_Monofield_GetValue", t
->type
);
1692 vtable
= mono_class_vtable (domain
, cf
->parent
);
1693 if (!vtable
->initialized
&& !(cf
->type
->attrs
& FIELD_ATTRIBUTE_LITERAL
))
1694 mono_runtime_class_init (vtable
);
1699 mono_field_static_get_value (vtable
, cf
, &o
);
1701 mono_field_get_value (obj
, cf
, &o
);
1706 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1707 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1710 /* Convert the Nullable structure into a boxed vtype */
1712 buf
= (guint8
*)vtable
->data
+ cf
->offset
;
1714 buf
= (guint8
*)obj
+ cf
->offset
;
1716 return mono_nullable_box (buf
, nklass
);
1719 /* boxed value type */
1720 klass
= mono_class_from_mono_type (cf
->type
);
1721 o
= mono_object_new (domain
, klass
);
1722 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1724 mono_field_static_get_value (vtable
, cf
, v
);
1726 mono_field_get_value (obj
, cf
, v
);
1733 ves_icall_MonoField_SetValueInternal (MonoReflectionField
*field
, MonoObject
*obj
, MonoObject
*value
)
1735 MonoClassField
*cf
= field
->field
;
1738 MONO_ARCH_SAVE_REGS
;
1740 if (field
->klass
->image
->assembly
->ref_only
)
1741 mono_raise_exception (mono_get_exception_invalid_operation (
1742 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1744 v
= (gchar
*) value
;
1745 if (!cf
->type
->byref
) {
1746 switch (cf
->type
->type
) {
1749 case MONO_TYPE_BOOLEAN
:
1752 case MONO_TYPE_CHAR
:
1761 case MONO_TYPE_VALUETYPE
:
1763 v
+= sizeof (MonoObject
);
1765 case MONO_TYPE_STRING
:
1766 case MONO_TYPE_OBJECT
:
1767 case MONO_TYPE_CLASS
:
1768 case MONO_TYPE_ARRAY
:
1769 case MONO_TYPE_SZARRAY
:
1772 case MONO_TYPE_GENERICINST
: {
1773 MonoGenericClass
*gclass
= cf
->type
->data
.generic_class
;
1774 g_assert (!gclass
->context
.class_inst
->is_open
);
1776 if (mono_class_is_nullable (mono_class_from_mono_type (cf
->type
))) {
1777 MonoClass
*nklass
= mono_class_from_mono_type (cf
->type
);
1778 MonoObject
*nullable
;
1781 * Convert the boxed vtype into a Nullable structure.
1782 * This is complicated by the fact that Nullables have
1783 * a variable structure.
1785 nullable
= mono_object_new (mono_domain_get (), nklass
);
1787 mono_nullable_init (mono_object_unbox (nullable
), value
, nklass
);
1789 v
= mono_object_unbox (nullable
);
1792 if (gclass
->container_class
->valuetype
&& (v
!= NULL
))
1793 v
+= sizeof (MonoObject
);
1797 g_error ("type 0x%x not handled in "
1798 "ves_icall_FieldInfo_SetValueInternal", cf
->type
->type
);
1803 if (cf
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
1804 MonoVTable
*vtable
= mono_class_vtable (mono_object_domain (field
), cf
->parent
);
1805 if (!vtable
->initialized
)
1806 mono_runtime_class_init (vtable
);
1807 mono_field_static_set_value (vtable
, cf
, v
);
1809 mono_field_set_value (obj
, cf
, v
);
1814 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField
*this)
1816 MonoObject
*o
= NULL
;
1817 MonoClassField
*field
= this->field
;
1819 MonoDomain
*domain
= mono_object_domain (this);
1821 MonoTypeEnum def_type
;
1822 const char *def_value
;
1824 MONO_ARCH_SAVE_REGS
;
1826 mono_class_init (field
->parent
);
1828 if (!(field
->type
->attrs
& FIELD_ATTRIBUTE_HAS_DEFAULT
))
1829 mono_raise_exception (mono_get_exception_invalid_operation (NULL
));
1831 if (field
->parent
->image
->dynamic
) {
1833 g_assert_not_reached ();
1836 def_value
= mono_class_get_field_default_value (field
, &def_type
);
1841 case MONO_TYPE_BOOLEAN
:
1844 case MONO_TYPE_CHAR
:
1852 case MONO_TYPE_R8
: {
1855 /* boxed value type */
1856 t
= g_new0 (MonoType
, 1);
1858 klass
= mono_class_from_mono_type (t
);
1860 o
= mono_object_new (domain
, klass
);
1861 v
= ((gchar
*) o
) + sizeof (MonoObject
);
1862 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, v
);
1865 case MONO_TYPE_STRING
:
1866 case MONO_TYPE_CLASS
:
1867 mono_get_constant_value_from_blob (domain
, def_type
, def_value
, &o
);
1870 g_assert_not_reached ();
1876 static MonoReflectionType
*
1877 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod
*rmethod
)
1879 MonoMethod
*method
= rmethod
->method
.method
;
1881 return mono_type_get_object (mono_object_domain (rmethod
), &method
->klass
->byval_arg
);
1884 /* From MonoProperty.cs */
1886 PInfo_Attributes
= 1,
1887 PInfo_GetMethod
= 1 << 1,
1888 PInfo_SetMethod
= 1 << 2,
1889 PInfo_ReflectedType
= 1 << 3,
1890 PInfo_DeclaringType
= 1 << 4,
1895 ves_icall_get_property_info (MonoReflectionProperty
*property
, MonoPropertyInfo
*info
, PInfo req_info
)
1897 MonoDomain
*domain
= mono_object_domain (property
);
1899 MONO_ARCH_SAVE_REGS
;
1901 if ((req_info
& PInfo_ReflectedType
) != 0)
1902 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->klass
->byval_arg
));
1903 else if ((req_info
& PInfo_DeclaringType
) != 0)
1904 MONO_STRUCT_SETREF (info
, parent
, mono_type_get_object (domain
, &property
->property
->parent
->byval_arg
));
1906 if ((req_info
& PInfo_Name
) != 0)
1907 MONO_STRUCT_SETREF (info
, name
, mono_string_new (domain
, property
->property
->name
));
1909 if ((req_info
& PInfo_Attributes
) != 0)
1910 info
->attrs
= property
->property
->attrs
;
1912 if ((req_info
& PInfo_GetMethod
) != 0)
1913 MONO_STRUCT_SETREF (info
, get
, property
->property
->get
?
1914 mono_method_get_object (domain
, property
->property
->get
, property
->klass
): NULL
);
1916 if ((req_info
& PInfo_SetMethod
) != 0)
1917 MONO_STRUCT_SETREF (info
, set
, property
->property
->set
?
1918 mono_method_get_object (domain
, property
->property
->set
, property
->klass
): NULL
);
1920 * There may be other methods defined for properties, though, it seems they are not exposed
1921 * in the reflection API
1926 ves_icall_get_event_info (MonoReflectionEvent
*event
, MonoEventInfo
*info
)
1928 MonoDomain
*domain
= mono_object_domain (event
);
1930 MONO_ARCH_SAVE_REGS
;
1932 info
->reflected_type
= mono_type_get_object (domain
, &event
->klass
->byval_arg
);
1933 info
->declaring_type
= mono_type_get_object (domain
, &event
->event
->parent
->byval_arg
);
1935 info
->name
= mono_string_new (domain
, event
->event
->name
);
1936 info
->attrs
= event
->event
->attrs
;
1937 info
->add_method
= event
->event
->add
? mono_method_get_object (domain
, event
->event
->add
, NULL
): NULL
;
1938 info
->remove_method
= event
->event
->remove
? mono_method_get_object (domain
, event
->event
->remove
, NULL
): NULL
;
1939 info
->raise_method
= event
->event
->raise
? mono_method_get_object (domain
, event
->event
->raise
, NULL
): NULL
;
1941 if (event
->event
->other
) {
1943 while (event
->event
->other
[n
])
1945 info
->other_methods
= mono_array_new (domain
, mono_defaults
.method_info_class
, n
);
1947 for (i
= 0; i
< n
; i
++)
1948 mono_array_setref (info
->other_methods
, i
, mono_method_get_object (domain
, event
->event
->other
[i
], NULL
));
1953 ves_icall_Type_GetInterfaces (MonoReflectionType
* type
)
1955 MonoDomain
*domain
= mono_object_domain (type
);
1957 GPtrArray
*ifaces
= NULL
;
1959 MonoClass
*class = mono_class_from_mono_type (type
->type
);
1962 MonoGenericContext
*context
= NULL
;
1964 MONO_ARCH_SAVE_REGS
;
1966 if (class->generic_class
&& class->generic_class
->context
.class_inst
->is_open
) {
1967 context
= mono_class_get_context (class);
1968 class = class->generic_class
->container_class
;
1971 mono_class_setup_vtable (class);
1973 slots
= mono_bitset_new (class->max_interface_id
+ 1, 0);
1975 for (parent
= class; parent
; parent
= parent
->parent
) {
1976 GPtrArray
*tmp_ifaces
= mono_class_get_implemented_interfaces (parent
);
1978 for (i
= 0; i
< tmp_ifaces
->len
; ++i
) {
1979 MonoClass
*ic
= g_ptr_array_index (tmp_ifaces
, i
);
1981 if (mono_bitset_test (slots
, ic
->interface_id
))
1984 mono_bitset_set (slots
, ic
->interface_id
);
1986 ifaces
= g_ptr_array_new ();
1987 g_ptr_array_add (ifaces
, ic
);
1989 g_ptr_array_free (tmp_ifaces
, TRUE
);
1992 mono_bitset_free (slots
);
1995 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
1997 intf
= mono_array_new (domain
, mono_defaults
.monotype_class
, ifaces
->len
);
1998 for (i
= 0; i
< ifaces
->len
; ++i
) {
1999 MonoClass
*ic
= g_ptr_array_index (ifaces
, i
);
2000 MonoType
*ret
= &ic
->byval_arg
, *inflated
= NULL
;
2001 if (context
&& ic
->generic_class
&& ic
->generic_class
->context
.class_inst
->is_open
)
2002 inflated
= ret
= mono_class_inflate_generic_type (ret
, context
);
2004 mono_array_setref (intf
, i
, mono_type_get_object (domain
, ret
));
2006 mono_metadata_free_type (inflated
);
2008 g_ptr_array_free (ifaces
, TRUE
);
2014 ves_icall_Type_GetInterfaceMapData (MonoReflectionType
*type
, MonoReflectionType
*iface
, MonoArray
**targets
, MonoArray
**methods
)
2016 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2017 MonoClass
*iclass
= mono_class_from_mono_type (iface
->type
);
2018 MonoReflectionMethod
*member
;
2021 int i
= 0, len
, ioffset
;
2024 MONO_ARCH_SAVE_REGS
;
2026 mono_class_setup_vtable (class);
2028 /* type doesn't implement iface: the exception is thrown in managed code */
2029 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass
->interface_id
))
2032 len
= mono_class_num_methods (iclass
);
2033 ioffset
= mono_class_interface_offset (class, iclass
);
2034 domain
= mono_object_domain (type
);
2035 *targets
= mono_array_new (domain
, mono_defaults
.method_info_class
, len
);
2036 *methods
= mono_array_new (domain
, mono_defaults
.method_info_class
, len
);
2039 while ((method
= mono_class_get_methods (iclass
, &iter
))) {
2040 member
= mono_method_get_object (domain
, method
, iclass
);
2041 mono_array_setref (*methods
, i
, member
);
2042 member
= mono_method_get_object (domain
, class->vtable
[i
+ ioffset
], class);
2043 mono_array_setref (*targets
, i
, member
);
2050 ves_icall_Type_GetPacking (MonoReflectionType
*type
, guint32
*packing
, guint32
*size
)
2052 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2054 if (klass
->image
->dynamic
) {
2055 MonoReflectionTypeBuilder
*tb
= (MonoReflectionTypeBuilder
*)type
;
2056 *packing
= tb
->packing_size
;
2057 *size
= tb
->class_size
;
2059 mono_metadata_packing_from_typedef (klass
->image
, klass
->type_token
, packing
, size
);
2063 static MonoReflectionType
*
2064 ves_icall_MonoType_GetElementType (MonoReflectionType
*type
)
2066 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2068 MONO_ARCH_SAVE_REGS
;
2070 // GetElementType should only return a type for:
2071 // Array Pointer PassedByRef
2072 if (type
->type
->byref
)
2073 return mono_type_get_object (mono_object_domain (type
), &class->byval_arg
);
2074 else if (class->element_class
&& MONO_CLASS_IS_ARRAY (class))
2075 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2076 else if (class->element_class
&& type
->type
->type
== MONO_TYPE_PTR
)
2077 return mono_type_get_object (mono_object_domain (type
), &class->element_class
->byval_arg
);
2082 static MonoReflectionType
*
2083 ves_icall_get_type_parent (MonoReflectionType
*type
)
2085 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2087 MONO_ARCH_SAVE_REGS
;
2089 return class->parent
? mono_type_get_object (mono_object_domain (type
), &class->parent
->byval_arg
): NULL
;
2093 ves_icall_type_ispointer (MonoReflectionType
*type
)
2095 MONO_ARCH_SAVE_REGS
;
2097 return type
->type
->type
== MONO_TYPE_PTR
;
2101 ves_icall_type_isprimitive (MonoReflectionType
*type
)
2103 MONO_ARCH_SAVE_REGS
;
2105 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
)));
2109 ves_icall_type_isbyref (MonoReflectionType
*type
)
2111 MONO_ARCH_SAVE_REGS
;
2113 return type
->type
->byref
;
2117 ves_icall_type_iscomobject (MonoReflectionType
*type
)
2119 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
2120 MONO_ARCH_SAVE_REGS
;
2122 return (klass
&& klass
->is_com_object
);
2125 static MonoReflectionModule
*
2126 ves_icall_MonoType_get_Module (MonoReflectionType
*type
)
2128 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2130 MONO_ARCH_SAVE_REGS
;
2132 return mono_module_get_object (mono_object_domain (type
), class->image
);
2135 static MonoReflectionAssembly
*
2136 ves_icall_MonoType_get_Assembly (MonoReflectionType
*type
)
2138 MonoDomain
*domain
= mono_domain_get ();
2139 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2141 MONO_ARCH_SAVE_REGS
;
2143 return mono_assembly_get_object (domain
, class->image
->assembly
);
2146 static MonoReflectionType
*
2147 ves_icall_MonoType_get_DeclaringType (MonoReflectionType
*type
)
2149 MonoDomain
*domain
= mono_domain_get ();
2152 MONO_ARCH_SAVE_REGS
;
2154 if (type
->type
->byref
)
2156 if (type
->type
->type
== MONO_TYPE_VAR
)
2157 class = type
->type
->data
.generic_param
->owner
->owner
.klass
;
2158 else if (type
->type
->type
== MONO_TYPE_MVAR
)
2159 class = type
->type
->data
.generic_param
->owner
->owner
.method
->klass
;
2161 class = mono_class_from_mono_type (type
->type
)->nested_in
;
2163 return class ? mono_type_get_object (domain
, &class->byval_arg
) : NULL
;
2166 static MonoReflectionType
*
2167 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType
*type
)
2169 MonoDomain
*domain
= mono_domain_get ();
2170 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2172 MONO_ARCH_SAVE_REGS
;
2174 if (class->enumtype
&& class->enum_basetype
) /* types that are modified typebuilders may not have enum_basetype set */
2175 return mono_type_get_object (domain
, class->enum_basetype
);
2176 else if (class->element_class
)
2177 return mono_type_get_object (domain
, &class->element_class
->byval_arg
);
2183 ves_icall_MonoType_get_Name (MonoReflectionType
*type
)
2185 MonoDomain
*domain
= mono_domain_get ();
2186 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2188 MONO_ARCH_SAVE_REGS
;
2190 if (type
->type
->byref
) {
2191 char *n
= g_strdup_printf ("%s&", class->name
);
2192 MonoString
*res
= mono_string_new (domain
, n
);
2198 return mono_string_new (domain
, class->name
);
2203 ves_icall_MonoType_get_Namespace (MonoReflectionType
*type
)
2205 MonoDomain
*domain
= mono_domain_get ();
2206 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2208 MONO_ARCH_SAVE_REGS
;
2210 while (class->nested_in
)
2211 class = class->nested_in
;
2213 if (class->name_space
[0] == '\0')
2216 return mono_string_new (domain
, class->name_space
);
2220 ves_icall_MonoType_GetArrayRank (MonoReflectionType
*type
)
2222 MonoClass
*class = mono_class_from_mono_type (type
->type
);
2224 MONO_ARCH_SAVE_REGS
;
2230 ves_icall_MonoType_GetGenericArguments (MonoReflectionType
*type
)
2233 MonoClass
*klass
, *pklass
;
2235 MONO_ARCH_SAVE_REGS
;
2237 klass
= mono_class_from_mono_type (type
->type
);
2239 if (klass
->generic_container
) {
2240 MonoGenericContainer
*container
= klass
->generic_container
;
2241 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, container
->type_argc
);
2242 for (i
= 0; i
< container
->type_argc
; ++i
) {
2243 pklass
= mono_class_from_generic_parameter (&container
->type_params
[i
], klass
->image
, FALSE
);
2244 mono_array_setref (res
, i
, mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
));
2246 } else if (klass
->generic_class
) {
2247 MonoGenericInst
*inst
= klass
->generic_class
->context
.class_inst
;
2248 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, inst
->type_argc
);
2249 for (i
= 0; i
< inst
->type_argc
; ++i
)
2250 mono_array_setref (res
, i
, mono_type_get_object (mono_object_domain (type
), inst
->type_argv
[i
]));
2252 res
= mono_array_new (mono_object_domain (type
), mono_defaults
.systemtype_class
, 0);
2258 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType
*type
)
2261 MONO_ARCH_SAVE_REGS
;
2263 if (type
->type
->byref
)
2266 klass
= mono_class_from_mono_type (type
->type
);
2268 return klass
->generic_container
!= NULL
;
2271 static MonoReflectionType
*
2272 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType
*type
)
2275 MONO_ARCH_SAVE_REGS
;
2277 if (type
->type
->byref
)
2280 klass
= mono_class_from_mono_type (type
->type
);
2281 if (klass
->generic_container
) {
2282 return type
; /* check this one */
2284 if (klass
->generic_class
) {
2285 MonoClass
*generic_class
= klass
->generic_class
->container_class
;
2287 if (generic_class
->wastypebuilder
&& generic_class
->reflection_info
)
2288 return generic_class
->reflection_info
;
2290 return mono_type_get_object (mono_object_domain (type
), &generic_class
->byval_arg
);
2295 static MonoReflectionType
*
2296 ves_icall_Type_MakeGenericType (MonoReflectionType
*type
, MonoArray
*type_array
)
2298 MonoType
*geninst
, **types
;
2301 MONO_ARCH_SAVE_REGS
;
2303 count
= mono_array_length (type_array
);
2304 types
= g_new0 (MonoType
*, count
);
2306 for (i
= 0; i
< count
; i
++) {
2307 MonoReflectionType
*t
= mono_array_get (type_array
, gpointer
, i
);
2308 types
[i
] = t
->type
;
2311 geninst
= mono_reflection_bind_generic_parameters (type
, count
, types
);
2316 return mono_type_get_object (mono_object_domain (type
), geninst
);
2320 ves_icall_Type_get_IsGenericInstance (MonoReflectionType
*type
)
2323 MONO_ARCH_SAVE_REGS
;
2325 if (type
->type
->byref
)
2328 klass
= mono_class_from_mono_type (type
->type
);
2329 return klass
->generic_class
!= NULL
;
2333 ves_icall_Type_get_IsGenericType (MonoReflectionType
*type
)
2336 MONO_ARCH_SAVE_REGS
;
2338 if (type
->type
->byref
)
2341 klass
= mono_class_from_mono_type (type
->type
);
2342 return klass
->generic_class
!= NULL
|| klass
->generic_container
!= NULL
;
2346 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType
*type
)
2348 MONO_ARCH_SAVE_REGS
;
2350 if (is_generic_parameter (type
->type
))
2351 return type
->type
->data
.generic_param
->num
;
2355 static GenericParameterAttributes
2356 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType
*type
)
2358 MONO_ARCH_SAVE_REGS
;
2359 g_assert (is_generic_parameter (type
->type
));
2360 return type
->type
->data
.generic_param
->flags
;
2364 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType
*type
)
2366 MonoGenericParam
*param
;
2372 MONO_ARCH_SAVE_REGS
;
2374 domain
= mono_object_domain (type
);
2375 param
= type
->type
->data
.generic_param
;
2376 for (count
= 0, ptr
= param
->constraints
; ptr
&& *ptr
; ptr
++, count
++)
2379 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
2380 for (i
= 0; i
< count
; i
++)
2381 mono_array_setref (res
, i
, mono_type_get_object (domain
, ¶m
->constraints
[i
]->byval_arg
));
2388 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType
*type
)
2390 MONO_ARCH_SAVE_REGS
;
2391 return is_generic_parameter (type
->type
);
2395 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder
*tb
)
2397 MONO_ARCH_SAVE_REGS
;
2398 return is_generic_parameter (tb
->type
.type
);
2402 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType
*enumtype
,
2403 MonoReflectionType
*t
)
2405 enumtype
->type
= t
->type
;
2408 static MonoReflectionType
*
2409 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass
*type
)
2411 MonoDynamicGenericClass
*gclass
;
2412 MonoReflectionType
*parent
= NULL
, *res
;
2418 MONO_ARCH_SAVE_REGS
;
2420 g_assert (type
->type
.type
->data
.generic_class
->is_dynamic
);
2421 gclass
= (MonoDynamicGenericClass
*) type
->type
.type
->data
.generic_class
;
2423 domain
= mono_object_domain (type
);
2424 klass
= mono_class_from_mono_type (type
->generic_type
->type
.type
);
2426 if (!klass
->generic_class
&& !klass
->generic_container
)
2429 parent
= type
->generic_type
->parent
;
2431 if (!parent
|| (parent
->type
->type
!= MONO_TYPE_GENERICINST
))
2434 inflated
= mono_class_inflate_generic_type (
2435 parent
->type
, mono_generic_class_get_context ((MonoGenericClass
*) gclass
));
2437 res
= mono_type_get_object (domain
, inflated
);
2438 mono_metadata_free_type (inflated
);
2443 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass
*type
)
2445 static MonoClass
*System_Reflection_MonoGenericClass
;
2446 MonoGenericClass
*gclass
;
2447 MonoReflectionTypeBuilder
*tb
= NULL
;
2448 MonoClass
*klass
= NULL
;
2453 MONO_ARCH_SAVE_REGS
;
2455 if (!System_Reflection_MonoGenericClass
) {
2456 System_Reflection_MonoGenericClass
= mono_class_from_name (
2457 mono_defaults
.corlib
, "System.Reflection", "MonoGenericClass");
2458 g_assert (System_Reflection_MonoGenericClass
);
2461 domain
= mono_object_domain (type
);
2463 gclass
= type
->type
.type
->data
.generic_class
;
2464 g_assert (gclass
->is_dynamic
);
2466 tb
= type
->generic_type
;
2467 icount
= tb
->interfaces
? mono_array_length (tb
->interfaces
) : 0;
2469 res
= mono_array_new (domain
, System_Reflection_MonoGenericClass
, icount
);
2471 for (i
= 0; i
< icount
; i
++) {
2472 MonoReflectionType
*iface
;
2476 iface
= mono_array_get (tb
->interfaces
, MonoReflectionType
*, i
);
2479 it
= &klass
->interfaces
[i
]->byval_arg
;
2481 it
= mono_class_inflate_generic_type (it
, mono_generic_class_get_context (gclass
));
2483 iface
= mono_type_get_object (domain
, it
);
2484 mono_array_setref (res
, i
, iface
);
2485 mono_metadata_free_type (it
);
2491 static MonoReflectionMethod
*
2492 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass
*type
,
2493 MonoReflectionMethod
* generic
)
2495 MonoGenericClass
*gclass
;
2496 MonoDynamicGenericClass
*dgclass
;
2500 MONO_ARCH_SAVE_REGS
;
2502 gclass
= type
->type
.type
->data
.generic_class
;
2503 g_assert (gclass
->is_dynamic
);
2505 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2507 domain
= mono_object_domain (type
);
2509 for (i
= 0; i
< dgclass
->count_methods
; i
++)
2510 if (generic
->method
->token
== dgclass
->methods
[i
]->token
)
2511 return mono_method_get_object (domain
, dgclass
->methods
[i
], NULL
);
2516 static MonoReflectionMethod
*
2517 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass
*type
,
2518 MonoReflectionMethod
* generic
)
2520 MonoGenericClass
*gclass
;
2521 MonoDynamicGenericClass
*dgclass
;
2525 MONO_ARCH_SAVE_REGS
;
2527 gclass
= type
->type
.type
->data
.generic_class
;
2528 g_assert (gclass
->is_dynamic
);
2530 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2532 domain
= mono_object_domain (type
);
2534 for (i
= 0; i
< dgclass
->count_ctors
; i
++)
2535 if (generic
->method
->token
== dgclass
->ctors
[i
]->token
)
2536 return mono_method_get_object (domain
, dgclass
->ctors
[i
], NULL
);
2542 static MonoReflectionField
*
2543 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass
*type
,
2544 MonoString
* generic_name
)
2546 MonoGenericClass
*gclass
;
2547 MonoDynamicGenericClass
*dgclass
;
2549 MonoClass
*refclass
;
2550 char *utf8_name
= mono_string_to_utf8 (generic_name
);
2553 MONO_ARCH_SAVE_REGS
;
2555 gclass
= type
->type
.type
->data
.generic_class
;
2556 g_assert (gclass
->is_dynamic
);
2558 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2560 refclass
= mono_class_from_mono_type (type
->type
.type
);
2562 domain
= mono_object_domain (type
);
2564 for (i
= 0; i
< dgclass
->count_fields
; i
++)
2565 if (strcmp (utf8_name
, mono_field_get_name (&dgclass
->fields
[i
])) == 0) {
2567 return mono_field_get_object (domain
, refclass
, &dgclass
->fields
[i
]);
2576 static MonoReflectionMethod
*
2577 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType
*type
,
2578 MonoReflectionMethod
* generic
)
2585 MONO_ARCH_SAVE_REGS
;
2587 domain
= ((MonoObject
*)type
)->vtable
->domain
;
2589 klass
= mono_class_from_mono_type (type
->type
);
2592 while ((method
= mono_class_get_methods (klass
, &iter
))) {
2593 if (method
->token
== generic
->method
->token
)
2594 return mono_method_get_object (domain
, method
, klass
);
2601 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass
*type
,
2602 MonoReflectionType
*reflected_type
)
2604 MonoGenericClass
*gclass
;
2605 MonoDynamicGenericClass
*dgclass
;
2607 MonoClass
*refclass
;
2611 MONO_ARCH_SAVE_REGS
;
2613 gclass
= type
->type
.type
->data
.generic_class
;
2614 g_assert (gclass
->is_dynamic
);
2615 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2617 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2619 domain
= mono_object_domain (type
);
2620 res
= mono_array_new (domain
, mono_defaults
.method_info_class
, dgclass
->count_methods
);
2622 for (i
= 0; i
< dgclass
->count_methods
; i
++)
2623 mono_array_setref (res
, i
, mono_method_get_object (domain
, dgclass
->methods
[i
], refclass
));
2629 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass
*type
,
2630 MonoReflectionType
*reflected_type
)
2632 static MonoClass
*System_Reflection_ConstructorInfo
;
2633 MonoGenericClass
*gclass
;
2634 MonoDynamicGenericClass
*dgclass
;
2636 MonoClass
*refclass
;
2640 MONO_ARCH_SAVE_REGS
;
2642 if (!System_Reflection_ConstructorInfo
)
2643 System_Reflection_ConstructorInfo
= mono_class_from_name (
2644 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
2646 gclass
= type
->type
.type
->data
.generic_class
;
2647 g_assert (gclass
->is_dynamic
);
2648 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2650 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2652 domain
= mono_object_domain (type
);
2653 res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, dgclass
->count_ctors
);
2655 for (i
= 0; i
< dgclass
->count_ctors
; i
++)
2656 mono_array_setref (res
, i
, mono_method_get_object (domain
, dgclass
->ctors
[i
], refclass
));
2662 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass
*type
,
2663 MonoReflectionType
*reflected_type
)
2665 MonoGenericClass
*gclass
;
2666 MonoDynamicGenericClass
*dgclass
;
2668 MonoClass
*refclass
;
2672 MONO_ARCH_SAVE_REGS
;
2674 gclass
= type
->type
.type
->data
.generic_class
;
2675 g_assert (gclass
->is_dynamic
);
2676 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2678 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2680 domain
= mono_object_domain (type
);
2681 res
= mono_array_new (domain
, mono_defaults
.field_info_class
, dgclass
->count_fields
);
2683 for (i
= 0; i
< dgclass
->count_fields
; i
++)
2684 mono_array_setref (res
, i
, mono_field_get_object (domain
, refclass
, &dgclass
->fields
[i
]));
2690 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass
*type
,
2691 MonoReflectionType
*reflected_type
)
2693 static MonoClass
*System_Reflection_PropertyInfo
;
2694 MonoGenericClass
*gclass
;
2695 MonoDynamicGenericClass
*dgclass
;
2697 MonoClass
*refclass
;
2701 MONO_ARCH_SAVE_REGS
;
2703 if (!System_Reflection_PropertyInfo
)
2704 System_Reflection_PropertyInfo
= mono_class_from_name (
2705 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
2707 gclass
= type
->type
.type
->data
.generic_class
;
2708 g_assert (gclass
->is_dynamic
);
2709 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2711 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2713 domain
= mono_object_domain (type
);
2714 res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, dgclass
->count_properties
);
2716 for (i
= 0; i
< dgclass
->count_properties
; i
++)
2717 mono_array_setref (res
, i
, mono_property_get_object (domain
, refclass
, &dgclass
->properties
[i
]));
2723 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass
*type
,
2724 MonoReflectionType
*reflected_type
)
2726 static MonoClass
*System_Reflection_EventInfo
;
2727 MonoGenericClass
*gclass
;
2728 MonoDynamicGenericClass
*dgclass
;
2730 MonoClass
*refclass
;
2734 MONO_ARCH_SAVE_REGS
;
2736 if (!System_Reflection_EventInfo
)
2737 System_Reflection_EventInfo
= mono_class_from_name (
2738 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
2740 gclass
= type
->type
.type
->data
.generic_class
;
2741 g_assert (gclass
->is_dynamic
);
2742 dgclass
= (MonoDynamicGenericClass
*) gclass
;
2744 refclass
= mono_class_from_mono_type (reflected_type
->type
);
2746 domain
= mono_object_domain (type
);
2747 res
= mono_array_new (domain
, System_Reflection_EventInfo
, dgclass
->count_events
);
2749 for (i
= 0; i
< dgclass
->count_events
; i
++)
2750 mono_array_setref (res
, i
, mono_event_get_object (domain
, refclass
, &dgclass
->events
[i
]));
2755 static MonoReflectionType
*
2756 ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass
*type
,
2757 MonoReflectionType
*target
)
2761 MonoReflectionType
*res
;
2763 MONO_ARCH_SAVE_REGS
;
2765 gklass
= mono_class_from_mono_type (type
->type
.type
);
2766 res_type
= mono_class_inflate_generic_type (target
->type
, mono_class_get_context (gklass
));
2767 res
= mono_type_get_object (mono_object_domain (type
), res_type
);
2768 mono_metadata_free_type (res_type
);
2772 static MonoReflectionMethod
*
2773 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType
*type
)
2778 MONO_ARCH_SAVE_REGS
;
2780 if (type
->type
->byref
|| type
->type
->type
!= MONO_TYPE_MVAR
)
2783 method
= type
->type
->data
.generic_param
->owner
->owner
.method
;
2785 klass
= mono_class_from_mono_type (type
->type
);
2786 return mono_method_get_object (mono_object_domain (type
), method
, klass
);
2789 static MonoReflectionDllImportAttribute
*
2790 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod
*method
)
2792 static MonoClass
*DllImportAttributeClass
= NULL
;
2793 MonoDomain
*domain
= mono_domain_get ();
2794 MonoReflectionDllImportAttribute
*attr
;
2795 MonoImage
*image
= method
->klass
->image
;
2796 MonoMethodPInvoke
*piinfo
= (MonoMethodPInvoke
*)method
;
2797 MonoTableInfo
*tables
= image
->tables
;
2798 MonoTableInfo
*im
= &tables
[MONO_TABLE_IMPLMAP
];
2799 MonoTableInfo
*mr
= &tables
[MONO_TABLE_MODULEREF
];
2800 guint32 im_cols
[MONO_IMPLMAP_SIZE
];
2801 guint32 scope_token
;
2802 const char *import
= NULL
;
2803 const char *scope
= NULL
;
2806 if (!method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
)
2809 if (!DllImportAttributeClass
) {
2810 DllImportAttributeClass
=
2811 mono_class_from_name (mono_defaults
.corlib
,
2812 "System.Runtime.InteropServices", "DllImportAttribute");
2813 g_assert (DllImportAttributeClass
);
2816 if (method
->klass
->image
->dynamic
) {
2817 MonoReflectionMethodAux
*method_aux
=
2818 g_hash_table_lookup (
2819 ((MonoDynamicImage
*)method
->klass
->image
)->method_aux_hash
, method
);
2821 import
= method_aux
->dllentry
;
2822 scope
= method_aux
->dll
;
2826 if (piinfo
->implmap_idx
) {
2827 mono_metadata_decode_row (im
, piinfo
->implmap_idx
- 1, im_cols
, MONO_IMPLMAP_SIZE
);
2829 piinfo
->piflags
= im_cols
[MONO_IMPLMAP_FLAGS
];
2830 import
= mono_metadata_string_heap (image
, im_cols
[MONO_IMPLMAP_NAME
]);
2831 scope_token
= mono_metadata_decode_row_col (mr
, im_cols
[MONO_IMPLMAP_SCOPE
] - 1, MONO_MODULEREF_NAME
);
2832 scope
= mono_metadata_string_heap (image
, scope_token
);
2835 flags
= piinfo
->piflags
;
2837 attr
= (MonoReflectionDllImportAttribute
*)mono_object_new (domain
, DllImportAttributeClass
);
2839 MONO_OBJECT_SETREF (attr
, dll
, mono_string_new (domain
, scope
));
2840 MONO_OBJECT_SETREF (attr
, entry_point
, mono_string_new (domain
, import
));
2841 attr
->call_conv
= (flags
& 0x700) >> 8;
2842 attr
->charset
= ((flags
& 0x6) >> 1) + 1;
2843 if (attr
->charset
== 1)
2845 attr
->exact_spelling
= (flags
& 0x1) != 0;
2846 attr
->set_last_error
= (flags
& 0x40) != 0;
2847 attr
->best_fit_mapping
= (flags
& 0x30) == 0x10;
2848 attr
->throw_on_unmappable
= (flags
& 0x3000) == 0x1000;
2849 attr
->preserve_sig
= FALSE
;
2854 static MonoReflectionMethod
*
2855 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod
*method
)
2857 MonoMethodInflated
*imethod
;
2860 MONO_ARCH_SAVE_REGS
;
2862 if (method
->method
->is_generic
)
2865 if (!method
->method
->is_inflated
)
2868 imethod
= (MonoMethodInflated
*) method
->method
;
2870 result
= imethod
->declaring
;
2871 /* Not a generic method. */
2872 if (!result
->is_generic
)
2875 if (method
->method
->klass
->image
->dynamic
) {
2876 MonoDynamicImage
*image
= (MonoDynamicImage
*)method
->method
->klass
->image
;
2877 MonoReflectionMethod
*res
;
2880 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2881 * the dynamic case as well ?
2883 mono_loader_lock ();
2884 res
= mono_g_hash_table_lookup (image
->generic_def_objects
, imethod
);
2885 mono_loader_unlock ();
2891 if (imethod
->context
.class_inst
) {
2892 MonoClass
*klass
= ((MonoMethod
*) imethod
)->klass
;
2893 result
= mono_class_inflate_generic_method_full (result
, klass
, mono_class_get_context (klass
));
2896 return mono_method_get_object (mono_object_domain (method
), result
, NULL
);
2900 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod
*method
)
2902 MONO_ARCH_SAVE_REGS
;
2904 return mono_method_signature (method
->method
)->generic_param_count
!= 0;
2908 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod
*method
)
2910 MONO_ARCH_SAVE_REGS
;
2912 return method
->method
->is_generic
;
2916 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod
*method
)
2921 MONO_ARCH_SAVE_REGS
;
2923 domain
= mono_object_domain (method
);
2925 if (method
->method
->is_inflated
) {
2926 MonoGenericInst
*inst
= mono_method_get_context (method
->method
)->method_inst
;
2929 count
= inst
->type_argc
;
2930 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2932 for (i
= 0; i
< count
; i
++)
2933 mono_array_setref (res
, i
, mono_type_get_object (domain
, inst
->type_argv
[i
]));
2939 count
= mono_method_signature (method
->method
)->generic_param_count
;
2940 res
= mono_array_new (domain
, mono_defaults
.systemtype_class
, count
);
2942 for (i
= 0; i
< count
; i
++) {
2943 MonoGenericContainer
*container
= mono_method_get_generic_container (method
->method
);
2944 MonoGenericParam
*param
= &container
->type_params
[i
];
2945 MonoClass
*pklass
= mono_class_from_generic_parameter (
2946 param
, method
->method
->klass
->image
, TRUE
);
2947 mono_array_setref (res
, i
,
2948 mono_type_get_object (domain
, &pklass
->byval_arg
));
2955 ensure_reflection_security (void)
2957 MonoMethod
*m
= mono_method_get_last_managed ();
2961 g_print ("method %s.%s.%s in image %s\n",
2962 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2965 /* We stop at the first method which is not in
2966 System.Reflection or which is not in a platform
2968 if (strcmp (m
->klass
->name_space
, "System.Reflection") != 0 ||
2969 !mono_security_core_clr_is_platform_image (m
->klass
->image
)) {
2970 /* If the method is transparent we throw an exception. */
2971 if (mono_security_core_clr_method_level (m
, TRUE
) == MONO_SECURITY_CORE_CLR_TRANSPARENT
) {
2972 MonoException
*ex
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System", "MethodAccessException", "Reflection called from transparent code");
2974 mono_raise_exception (ex
);
2979 mono_stack_walk_no_il (get_caller
, &m
);
2984 ves_icall_InternalInvoke (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoException
**exc
)
2987 * Invoke from reflection is supposed to always be a virtual call (the API
2988 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2989 * greater flexibility.
2991 MonoMethod
*m
= method
->method
;
2995 MONO_ARCH_SAVE_REGS
;
2999 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR
&&
3000 mono_security_core_clr_method_level (m
, TRUE
) == MONO_SECURITY_CORE_CLR_CRITICAL
)
3001 ensure_reflection_security ();
3003 if (!(m
->flags
& METHOD_ATTRIBUTE_STATIC
)) {
3005 if (!mono_object_isinst (this, m
->klass
)) {
3006 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Object does not match target type.");
3009 m
= mono_object_get_virtual_method (this, m
);
3010 /* must pass the pointer to the value for valuetype methods */
3011 if (m
->klass
->valuetype
)
3012 obj
= mono_object_unbox (this);
3013 } else if (strcmp (m
->name
, ".ctor") && !m
->wrapper_type
) {
3014 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Non-static method requires a target.");
3019 pcount
= params
? mono_array_length (params
): 0;
3020 if (pcount
!= mono_method_signature (m
)->param_count
) {
3021 *exc
= mono_exception_from_name (mono_defaults
.corlib
, "System.Reflection", "TargetParameterCountException");
3025 if ((m
->klass
->flags
& TYPE_ATTRIBUTE_ABSTRACT
) && !strcmp (m
->name
, ".ctor") && !this) {
3026 *exc
= mono_exception_from_name_msg (mono_defaults
.corlib
, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
3030 if (m
->klass
->image
->assembly
->ref_only
) {
3031 *exc
= mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
3035 if (m
->klass
->rank
&& !strcmp (m
->name
, ".ctor")) {
3037 mono_array_size_t
*lengths
;
3038 mono_array_size_t
*lower_bounds
;
3039 pcount
= mono_array_length (params
);
3040 lengths
= alloca (sizeof (mono_array_size_t
) * pcount
);
3041 for (i
= 0; i
< pcount
; ++i
)
3042 lengths
[i
] = *(mono_array_size_t
*) ((char*)mono_array_get (params
, gpointer
, i
) + sizeof (MonoObject
));
3044 if (m
->klass
->rank
== pcount
) {
3045 /* Only lengths provided. */
3046 lower_bounds
= NULL
;
3048 g_assert (pcount
== (m
->klass
->rank
* 2));
3049 /* lower bounds are first. */
3050 lower_bounds
= lengths
;
3051 lengths
+= m
->klass
->rank
;
3054 return (MonoObject
*)mono_array_new_full (mono_object_domain (params
), m
->klass
, lengths
, lower_bounds
);
3056 return mono_runtime_invoke_array (m
, obj
, params
, NULL
);
3060 ves_icall_InternalExecute (MonoReflectionMethod
*method
, MonoObject
*this, MonoArray
*params
, MonoArray
**outArgs
)
3062 MonoDomain
*domain
= mono_object_domain (method
);
3063 MonoMethod
*m
= method
->method
;
3064 MonoMethodSignature
*sig
= mono_method_signature (m
);
3065 MonoArray
*out_args
;
3067 int i
, j
, outarg_count
= 0;
3069 MONO_ARCH_SAVE_REGS
;
3071 if (m
->klass
== mono_defaults
.object_class
) {
3073 if (!strcmp (m
->name
, "FieldGetter")) {
3074 MonoClass
*k
= this->vtable
->klass
;
3078 /* If this is a proxy, then it must be a CBO */
3079 if (k
== mono_defaults
.transparent_proxy_class
) {
3080 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
3081 this = tp
->rp
->unwrapped_server
;
3083 k
= this->vtable
->klass
;
3086 name
= mono_array_get (params
, MonoString
*, 1);
3087 str
= mono_string_to_utf8 (name
);
3090 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3092 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3093 if (field_klass
->valuetype
)
3094 result
= mono_value_box (domain
, field_klass
, (char *)this + field
->offset
);
3096 result
= *((gpointer
*)((char *)this + field
->offset
));
3098 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 1);
3099 *outArgs
= out_args
;
3100 mono_array_setref (out_args
, 0, result
);
3108 g_assert_not_reached ();
3110 } else if (!strcmp (m
->name
, "FieldSetter")) {
3111 MonoClass
*k
= this->vtable
->klass
;
3117 /* If this is a proxy, then it must be a CBO */
3118 if (k
== mono_defaults
.transparent_proxy_class
) {
3119 MonoTransparentProxy
*tp
= (MonoTransparentProxy
*) this;
3120 this = tp
->rp
->unwrapped_server
;
3122 k
= this->vtable
->klass
;
3125 name
= mono_array_get (params
, MonoString
*, 1);
3126 str
= mono_string_to_utf8 (name
);
3129 MonoClassField
* field
= mono_class_get_field_from_name (k
, str
);
3131 MonoClass
*field_klass
= mono_class_from_mono_type (field
->type
);
3132 MonoObject
*val
= mono_array_get (params
, gpointer
, 2);
3134 if (field_klass
->valuetype
) {
3135 size
= mono_type_size (field
->type
, &align
);
3136 memcpy ((char *)this + field
->offset
,
3137 ((char *)val
) + sizeof (MonoObject
), size
);
3139 *(MonoObject
**)((char *)this + field
->offset
) = val
;
3141 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, 0);
3142 *outArgs
= out_args
;
3152 g_assert_not_reached ();
3157 for (i
= 0; i
< mono_array_length (params
); i
++) {
3158 if (sig
->params
[i
]->byref
)
3162 out_args
= mono_array_new (domain
, mono_defaults
.object_class
, outarg_count
);
3164 /* handle constructors only for objects already allocated */
3165 if (!strcmp (method
->method
->name
, ".ctor"))
3168 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3169 g_assert (!method
->method
->klass
->valuetype
);
3170 result
= mono_runtime_invoke_array (method
->method
, this, params
, NULL
);
3172 for (i
= 0, j
= 0; i
< mono_array_length (params
); i
++) {
3173 if (sig
->params
[i
]->byref
) {
3175 arg
= mono_array_get (params
, gpointer
, i
);
3176 mono_array_setref (out_args
, j
, arg
);
3181 *outArgs
= out_args
;
3187 read_enum_value (char *mem
, int type
)
3191 return *(guint8
*)mem
;
3193 return *(gint8
*)mem
;
3195 return *(guint16
*)mem
;
3197 return *(gint16
*)mem
;
3199 return *(guint32
*)mem
;
3201 return *(gint32
*)mem
;
3203 return *(guint64
*)mem
;
3205 return *(gint64
*)mem
;
3207 g_assert_not_reached ();
3213 write_enum_value (char *mem
, int type
, guint64 value
)
3217 case MONO_TYPE_I1
: {
3218 guint8
*p
= (guint8
*)mem
;
3223 case MONO_TYPE_I2
: {
3224 guint16
*p
= (void*)mem
;
3229 case MONO_TYPE_I4
: {
3230 guint32
*p
= (void*)mem
;
3235 case MONO_TYPE_I8
: {
3236 guint64
*p
= (void*)mem
;
3241 g_assert_not_reached ();
3247 ves_icall_System_Enum_ToObject (MonoReflectionType
*enumType
, MonoObject
*value
)
3250 MonoClass
*enumc
, *objc
;
3254 MONO_ARCH_SAVE_REGS
;
3256 MONO_CHECK_ARG_NULL (enumType
);
3257 MONO_CHECK_ARG_NULL (value
);
3259 domain
= mono_object_domain (enumType
);
3260 enumc
= mono_class_from_mono_type (enumType
->type
);
3261 objc
= value
->vtable
->klass
;
3263 if (!enumc
->enumtype
)
3264 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3265 if (!((objc
->enumtype
) || (objc
->byval_arg
.type
>= MONO_TYPE_I1
&& objc
->byval_arg
.type
<= MONO_TYPE_U8
)))
3266 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."));
3268 res
= mono_object_new (domain
, enumc
);
3269 val
= read_enum_value ((char *)value
+ sizeof (MonoObject
), objc
->enumtype
? objc
->enum_basetype
->type
: objc
->byval_arg
.type
);
3270 write_enum_value ((char *)res
+ sizeof (MonoObject
), enumc
->enum_basetype
->type
, val
);
3276 ves_icall_System_Enum_get_value (MonoObject
*this)
3284 MONO_ARCH_SAVE_REGS
;
3289 g_assert (this->vtable
->klass
->enumtype
);
3291 enumc
= mono_class_from_mono_type (this->vtable
->klass
->enum_basetype
);
3292 res
= mono_object_new (mono_object_domain (this), enumc
);
3293 dst
= (char *)res
+ sizeof (MonoObject
);
3294 src
= (char *)this + sizeof (MonoObject
);
3295 size
= mono_class_value_size (enumc
, NULL
);
3297 memcpy (dst
, src
, size
);
3302 static MonoReflectionType
*
3303 ves_icall_System_Enum_get_underlying_type (MonoReflectionType
*type
)
3305 MONO_ARCH_SAVE_REGS
;
3307 return mono_type_get_object (mono_object_domain (type
), mono_class_from_mono_type (type
->type
)->enum_basetype
);
3311 ves_icall_System_Enum_get_hashcode (MonoObject
*this)
3313 gpointer data
= (char *)this + sizeof (MonoObject
);
3314 MonoType
*basetype
= this->vtable
->klass
->enum_basetype
;
3315 g_assert (basetype
);
3317 switch (basetype
->type
) {
3319 return *((gint8
*)data
);
3321 return *((guint8
*)data
);
3322 case MONO_TYPE_CHAR
:
3324 return *((guint16
*)data
);
3327 return *((gint16
*)data
);
3329 return *((guint32
*)data
);
3331 return *((gint32
*)data
);
3333 case MONO_TYPE_I8
: {
3334 gint64 value
= *((gint64
*)data
);
3335 return (gint
)(value
& 0xffffffff) ^ (int)(value
>> 32);
3338 g_error ("Implement type 0x%02x in get_hashcode", basetype
->type
);
3344 ves_icall_get_enum_info (MonoReflectionType
*type
, MonoEnumInfo
*info
)
3346 MonoDomain
*domain
= mono_object_domain (type
);
3347 MonoClass
*enumc
= mono_class_from_mono_type (type
->type
);
3348 guint j
= 0, nvalues
, crow
;
3350 MonoClassField
*field
;
3352 MONO_ARCH_SAVE_REGS
;
3354 info
->utype
= mono_type_get_object (domain
, enumc
->enum_basetype
);
3355 nvalues
= mono_class_num_fields (enumc
) ? mono_class_num_fields (enumc
) - 1 : 0;
3356 info
->names
= mono_array_new (domain
, mono_defaults
.string_class
, nvalues
);
3357 info
->values
= mono_array_new (domain
, enumc
, nvalues
);
3361 while ((field
= mono_class_get_fields (enumc
, &iter
))) {
3364 MonoTypeEnum def_type
;
3366 if (strcmp ("value__", mono_field_get_name (field
)) == 0)
3368 if (mono_field_is_deleted (field
))
3370 mono_array_setref (info
->names
, j
, mono_string_new (domain
, mono_field_get_name (field
)));
3372 p
= mono_class_get_field_default_value (field
, &def_type
);
3373 len
= mono_metadata_decode_blob_size (p
, &p
);
3374 switch (enumc
->enum_basetype
->type
) {
3377 mono_array_set (info
->values
, gchar
, j
, *p
);
3379 case MONO_TYPE_CHAR
:
3382 mono_array_set (info
->values
, gint16
, j
, read16 (p
));
3386 mono_array_set (info
->values
, gint32
, j
, read32 (p
));
3390 mono_array_set (info
->values
, gint64
, j
, read64 (p
));
3393 g_error ("Implement type 0x%02x in get_enum_info", enumc
->enum_basetype
->type
);
3400 BFLAGS_IgnoreCase
= 1,
3401 BFLAGS_DeclaredOnly
= 2,
3402 BFLAGS_Instance
= 4,
3404 BFLAGS_Public
= 0x10,
3405 BFLAGS_NonPublic
= 0x20,
3406 BFLAGS_FlattenHierarchy
= 0x40,
3407 BFLAGS_InvokeMethod
= 0x100,
3408 BFLAGS_CreateInstance
= 0x200,
3409 BFLAGS_GetField
= 0x400,
3410 BFLAGS_SetField
= 0x800,
3411 BFLAGS_GetProperty
= 0x1000,
3412 BFLAGS_SetProperty
= 0x2000,
3413 BFLAGS_ExactBinding
= 0x10000,
3414 BFLAGS_SuppressChangeType
= 0x20000,
3415 BFLAGS_OptionalParamBinding
= 0x40000
3418 static MonoReflectionField
*
3419 ves_icall_Type_GetField (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3422 MonoClass
*startklass
, *klass
;
3424 MonoClassField
*field
;
3427 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3428 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3429 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3431 MONO_ARCH_SAVE_REGS
;
3434 mono_raise_exception (mono_get_exception_argument_null ("name"));
3435 if (type
->type
->byref
)
3438 compare_func
= (bflags
& BFLAGS_IgnoreCase
) ? g_strcasecmp
: strcmp
;
3441 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3442 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3445 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3448 if (field
->type
== NULL
)
3450 if (mono_field_is_deleted (field
))
3452 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3453 if (bflags
& BFLAGS_Public
)
3455 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3456 if (bflags
& BFLAGS_NonPublic
) {
3463 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3464 if (bflags
& BFLAGS_Static
)
3465 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3468 if (bflags
& BFLAGS_Instance
)
3475 utf8_name
= mono_string_to_utf8 (name
);
3477 if (compare_func (mono_field_get_name (field
), utf8_name
)) {
3483 return mono_field_get_object (domain
, klass
, field
);
3485 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3492 ves_icall_Type_GetFields_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3495 MonoClass
*startklass
, *klass
, *refklass
;
3500 MonoClassField
*field
;
3502 MONO_ARCH_SAVE_REGS
;
3504 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3505 if (type
->type
->byref
)
3506 return mono_array_new (domain
, mono_defaults
.field_info_class
, 0);
3507 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3508 refklass
= mono_class_from_mono_type (reftype
->type
);
3512 res
= mono_array_new (domain
, mono_defaults
.field_info_class
, len
);
3514 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3515 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3518 while ((field
= mono_class_get_fields (klass
, &iter
))) {
3520 if (mono_field_is_deleted (field
))
3522 if ((field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) == FIELD_ATTRIBUTE_PUBLIC
) {
3523 if (bflags
& BFLAGS_Public
)
3525 } else if ((klass
== startklass
) || (field
->type
->attrs
& FIELD_ATTRIBUTE_FIELD_ACCESS_MASK
) != FIELD_ATTRIBUTE_PRIVATE
) {
3526 if (bflags
& BFLAGS_NonPublic
) {
3533 if (field
->type
->attrs
& FIELD_ATTRIBUTE_STATIC
) {
3534 if (bflags
& BFLAGS_Static
)
3535 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3538 if (bflags
& BFLAGS_Instance
)
3544 member
= (MonoObject
*)mono_field_get_object (domain
, refklass
, field
);
3546 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.field_info_class
, len
* 2);
3547 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3551 mono_array_setref (res
, i
, member
);
3554 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3557 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.field_info_class
, i
);
3558 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3561 * Better solution for the new GC.
3562 * res->max_length = i;
3569 method_nonpublic (MonoMethod
* method
, gboolean start_klass
)
3571 switch (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) {
3572 case METHOD_ATTRIBUTE_ASSEM
:
3573 return (start_klass
|| mono_defaults
.generic_ilist_class
);
3574 case METHOD_ATTRIBUTE_PRIVATE
:
3576 case METHOD_ATTRIBUTE_PUBLIC
:
3584 ves_icall_Type_GetMethodsByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3586 static MonoClass
*MethodInfo_array
;
3588 MonoClass
*startklass
, *klass
, *refklass
;
3593 int i
, len
, match
, nslots
;
3594 guint32 method_slots_default
[8];
3595 guint32
*method_slots
;
3596 gchar
*mname
= NULL
;
3597 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3598 MonoVTable
*array_vtable
;
3600 MONO_ARCH_SAVE_REGS
;
3602 if (!MethodInfo_array
) {
3603 MonoClass
*klass
= mono_array_class_get (mono_defaults
.method_info_class
, 1);
3604 mono_memory_barrier ();
3605 MethodInfo_array
= klass
;
3608 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3609 array_vtable
= mono_class_vtable (domain
, MethodInfo_array
);
3610 if (type
->type
->byref
)
3611 return mono_array_new_specific (array_vtable
, 0);
3612 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3613 refklass
= mono_class_from_mono_type (reftype
->type
);
3616 mname
= mono_string_to_utf8 (name
);
3617 compare_func
= (ignore_case
) ? g_strcasecmp
: strcmp
;
3620 mono_class_setup_vtable (klass
);
3622 if (is_generic_parameter (type
->type
))
3623 nslots
= klass
->parent
->vtable_size
;
3625 nslots
= MONO_CLASS_IS_INTERFACE (klass
) ? mono_class_num_methods (klass
) : klass
->vtable_size
;
3626 if (nslots
>= sizeof (method_slots_default
) * 8) {
3627 method_slots
= g_new0 (guint32
, nslots
/ 32 + 1);
3629 method_slots
= method_slots_default
;
3630 memset (method_slots
, 0, sizeof (method_slots_default
));
3634 res
= mono_array_new_specific (array_vtable
, len
);
3636 mono_class_setup_vtable (klass
);
3637 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3638 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3641 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3643 if (method
->name
[0] == '.' && (strcmp (method
->name
, ".ctor") == 0 || strcmp (method
->name
, ".cctor") == 0))
3645 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3646 if (bflags
& BFLAGS_Public
)
3648 } else if ((bflags
& BFLAGS_NonPublic
) && method_nonpublic (method
, (klass
== startklass
))) {
3654 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3655 if (bflags
& BFLAGS_Static
)
3656 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3659 if (bflags
& BFLAGS_Instance
)
3667 if (compare_func (mname
, method
->name
))
3672 if (method
->slot
!= -1) {
3673 g_assert (method
->slot
< nslots
);
3674 if (method_slots
[method
->slot
>> 5] & (1 << (method
->slot
& 0x1f)))
3676 method_slots
[method
->slot
>> 5] |= 1 << (method
->slot
& 0x1f);
3679 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3682 MonoArray
*new_res
= mono_array_new_specific (array_vtable
, len
* 2);
3683 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3687 mono_array_setref (res
, i
, member
);
3690 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
3694 if (method_slots
!= method_slots_default
)
3695 g_free (method_slots
);
3697 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.method_info_class
, i
);
3698 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3701 * Better solution for the new GC.
3702 * res->max_length = i;
3709 ves_icall_Type_GetConstructors_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
3712 static MonoClass
*System_Reflection_ConstructorInfo
;
3713 MonoClass
*startklass
, *klass
, *refklass
;
3718 gpointer iter
= NULL
;
3720 MONO_ARCH_SAVE_REGS
;
3722 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3723 if (type
->type
->byref
)
3724 return mono_array_new (domain
, mono_defaults
.method_info_class
, 0);
3725 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3726 refklass
= mono_class_from_mono_type (reftype
->type
);
3728 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3729 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3731 if (!System_Reflection_ConstructorInfo
)
3732 System_Reflection_ConstructorInfo
= mono_class_from_name (
3733 mono_defaults
.corlib
, "System.Reflection", "ConstructorInfo");
3737 res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, len
);
3739 while ((method
= mono_class_get_methods (klass
, &iter
))) {
3741 if (strcmp (method
->name
, ".ctor") && strcmp (method
->name
, ".cctor"))
3743 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3744 if (bflags
& BFLAGS_Public
)
3747 if (bflags
& BFLAGS_NonPublic
)
3753 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3754 if (bflags
& BFLAGS_Static
)
3755 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3758 if (bflags
& BFLAGS_Instance
)
3764 member
= (MonoObject
*)mono_method_get_object (domain
, method
, refklass
);
3767 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, len
* 2);
3768 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3772 mono_array_setref (res
, i
, member
);
3776 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_ConstructorInfo
, i
);
3777 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3780 * Better solution for the new GC.
3781 * res->max_length = i;
3788 property_hash (gconstpointer data
)
3790 MonoProperty
*prop
= (MonoProperty
*)data
;
3792 return g_str_hash (prop
->name
);
3796 property_equal (MonoProperty
*prop1
, MonoProperty
*prop2
)
3798 // Properties are hide-by-name-and-signature
3799 if (!g_str_equal (prop1
->name
, prop2
->name
))
3802 if (prop1
->get
&& prop2
->get
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->get
), mono_method_signature (prop2
->get
)))
3804 if (prop1
->set
&& prop2
->set
&& !mono_metadata_signature_equal (mono_method_signature (prop1
->set
), mono_method_signature (prop2
->set
)))
3810 property_accessor_nonpublic (MonoMethod
* accessor
, gboolean start_klass
)
3815 return method_nonpublic (accessor
, start_klass
);
3819 ves_icall_Type_GetPropertiesByName (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
, MonoBoolean ignore_case
, MonoReflectionType
*reftype
)
3822 static MonoClass
*System_Reflection_PropertyInfo
;
3823 MonoClass
*startklass
, *klass
;
3830 gchar
*propname
= NULL
;
3831 int (*compare_func
) (const char *s1
, const char *s2
) = NULL
;
3833 GHashTable
*properties
;
3835 MONO_ARCH_SAVE_REGS
;
3837 if (!System_Reflection_PropertyInfo
)
3838 System_Reflection_PropertyInfo
= mono_class_from_name (
3839 mono_defaults
.corlib
, "System.Reflection", "PropertyInfo");
3841 domain
= ((MonoObject
*)type
)->vtable
->domain
;
3842 if (type
->type
->byref
)
3843 return mono_array_new (domain
, System_Reflection_PropertyInfo
, 0);
3844 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3846 propname
= mono_string_to_utf8 (name
);
3847 compare_func
= (ignore_case
) ? g_strcasecmp
: strcmp
;
3850 mono_class_setup_vtable (klass
);
3852 properties
= g_hash_table_new (property_hash
, (GEqualFunc
)property_equal
);
3855 res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, len
);
3857 mono_class_setup_vtable (klass
);
3858 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
) {
3859 g_hash_table_destroy (properties
);
3862 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3866 while ((prop
= mono_class_get_properties (klass
, &iter
))) {
3872 flags
= method
->flags
;
3875 if ((prop
->get
&& ((prop
->get
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
)) ||
3876 (prop
->set
&& ((prop
->set
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
))) {
3877 if (bflags
& BFLAGS_Public
)
3879 } else if (bflags
& BFLAGS_NonPublic
) {
3880 if (property_accessor_nonpublic(prop
->get
, startklass
== klass
) ||
3881 property_accessor_nonpublic(prop
->set
, startklass
== klass
)) {
3888 if (flags
& METHOD_ATTRIBUTE_STATIC
) {
3889 if (bflags
& BFLAGS_Static
)
3890 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
3893 if (bflags
& BFLAGS_Instance
)
3902 if (compare_func (propname
, prop
->name
))
3906 if (g_hash_table_lookup (properties
, prop
))
3910 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, len
* 2);
3911 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
3915 mono_array_setref (res
, i
, mono_property_get_object (domain
, startklass
, prop
));
3918 g_hash_table_insert (properties
, prop
, prop
);
3920 if ((!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
)))
3923 g_hash_table_destroy (properties
);
3926 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_PropertyInfo
, i
);
3927 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
3930 * Better solution for the new GC.
3931 * res->max_length = i;
3937 static MonoReflectionEvent
*
3938 ves_icall_MonoType_GetEvent (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
3941 MonoClass
*klass
, *startklass
;
3947 MONO_ARCH_SAVE_REGS
;
3949 event_name
= mono_string_to_utf8 (name
);
3950 if (type
->type
->byref
)
3952 klass
= startklass
= mono_class_from_mono_type (type
->type
);
3953 domain
= mono_object_domain (type
);
3956 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
3957 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
3960 while ((event
= mono_class_get_events (klass
, &iter
))) {
3961 if (strcmp (event
->name
, event_name
))
3964 method
= event
->add
;
3966 method
= event
->remove
;
3968 method
= event
->raise
;
3970 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
3971 if (!(bflags
& BFLAGS_Public
))
3974 if (!(bflags
& BFLAGS_NonPublic
))
3976 if ((klass
!= startklass
) && (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PRIVATE
)
3981 if (!(bflags
& BFLAGS_NonPublic
))
3984 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
3985 if (!(bflags
& BFLAGS_Static
))
3987 if (!(bflags
& BFLAGS_FlattenHierarchy
) && (klass
!= startklass
))
3990 if (!(bflags
& BFLAGS_Instance
))
3994 g_free (event_name
);
3995 return mono_event_get_object (domain
, startklass
, event
);
3998 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4001 g_free (event_name
);
4006 ves_icall_Type_GetEvents_internal (MonoReflectionType
*type
, guint32 bflags
, MonoReflectionType
*reftype
)
4009 static MonoClass
*System_Reflection_EventInfo
;
4010 MonoClass
*startklass
, *klass
;
4017 MONO_ARCH_SAVE_REGS
;
4019 if (!System_Reflection_EventInfo
)
4020 System_Reflection_EventInfo
= mono_class_from_name (
4021 mono_defaults
.corlib
, "System.Reflection", "EventInfo");
4023 domain
= mono_object_domain (type
);
4024 if (type
->type
->byref
)
4025 return mono_array_new (domain
, System_Reflection_EventInfo
, 0);
4026 klass
= startklass
= mono_class_from_mono_type (type
->type
);
4030 res
= mono_array_new (domain
, System_Reflection_EventInfo
, len
);
4032 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4033 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4036 while ((event
= mono_class_get_events (klass
, &iter
))) {
4038 method
= event
->add
;
4040 method
= event
->remove
;
4042 method
= event
->raise
;
4044 if ((method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) == METHOD_ATTRIBUTE_PUBLIC
) {
4045 if (bflags
& BFLAGS_Public
)
4047 } else if ((klass
== startklass
) || (method
->flags
& METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK
) != METHOD_ATTRIBUTE_PRIVATE
) {
4048 if (bflags
& BFLAGS_NonPublic
)
4053 if (bflags
& BFLAGS_NonPublic
)
4059 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
) {
4060 if (bflags
& BFLAGS_Static
)
4061 if ((bflags
& BFLAGS_FlattenHierarchy
) || (klass
== startklass
))
4064 if (bflags
& BFLAGS_Instance
)
4069 if (bflags
& BFLAGS_Instance
)
4075 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_EventInfo
, len
* 2);
4076 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
4080 mono_array_setref (res
, i
, mono_event_get_object (domain
, startklass
, event
));
4083 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4086 MonoArray
*new_res
= mono_array_new (domain
, System_Reflection_EventInfo
, i
);
4087 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
4090 * Better solution for the new GC.
4091 * res->max_length = i;
4097 static MonoReflectionType
*
4098 ves_icall_Type_GetNestedType (MonoReflectionType
*type
, MonoString
*name
, guint32 bflags
)
4106 MONO_ARCH_SAVE_REGS
;
4108 domain
= ((MonoObject
*)type
)->vtable
->domain
;
4109 if (type
->type
->byref
)
4111 klass
= mono_class_from_mono_type (type
->type
);
4112 str
= mono_string_to_utf8 (name
);
4115 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4116 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4119 * If a nested type is generic, return its generic type definition.
4120 * Note that this means that the return value is essentially a
4121 * nested type of the generic type definition of @klass.
4123 * A note in MSDN claims that a generic type definition can have
4124 * nested types that aren't generic. In any case, the container of that
4125 * nested type would be the generic type definition.
4127 if (klass
->generic_class
)
4128 klass
= klass
->generic_class
->container_class
;
4131 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4133 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4134 if (bflags
& BFLAGS_Public
)
4137 if (bflags
& BFLAGS_NonPublic
)
4142 if (strcmp (nested
->name
, str
) == 0){
4144 return mono_type_get_object (domain
, &nested
->byval_arg
);
4147 if (!(bflags
& BFLAGS_DeclaredOnly
) && (klass
= klass
->parent
))
4154 ves_icall_Type_GetNestedTypes (MonoReflectionType
*type
, guint32 bflags
)
4164 MONO_ARCH_SAVE_REGS
;
4166 domain
= ((MonoObject
*)type
)->vtable
->domain
;
4167 if (type
->type
->byref
)
4168 return mono_array_new (domain
, mono_defaults
.monotype_class
, 0);
4169 klass
= mono_class_from_mono_type (type
->type
);
4170 if (klass
->exception_type
!= MONO_EXCEPTION_NONE
)
4171 mono_raise_exception (mono_class_get_exception_for_failure (klass
));
4174 * If a nested type is generic, return its generic type definition.
4175 * Note that this means that the return value is essentially the set
4176 * of nested types of the generic type definition of @klass.
4178 * A note in MSDN claims that a generic type definition can have
4179 * nested types that aren't generic. In any case, the container of that
4180 * nested type would be the generic type definition.
4182 if (klass
->generic_class
)
4183 klass
= klass
->generic_class
->container_class
;
4187 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, len
);
4189 while ((nested
= mono_class_get_nested_types (klass
, &iter
))) {
4191 if ((nested
->flags
& TYPE_ATTRIBUTE_VISIBILITY_MASK
) == TYPE_ATTRIBUTE_NESTED_PUBLIC
) {
4192 if (bflags
& BFLAGS_Public
)
4195 if (bflags
& BFLAGS_NonPublic
)
4200 member
= (MonoObject
*)mono_type_get_object (domain
, &nested
->byval_arg
);
4202 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.monotype_class
, len
* 2);
4203 mono_array_memcpy_refs (new_res
, 0, res
, 0, len
);
4207 mono_array_setref (res
, i
, member
);
4211 MonoArray
*new_res
= mono_array_new (domain
, mono_defaults
.monotype_class
, i
);
4212 mono_array_memcpy_refs (new_res
, 0, res
, 0, i
);
4215 * Better solution for the new GC.
4216 * res->max_length = i;
4222 static MonoReflectionType
*
4223 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly
*assembly
, MonoReflectionModule
*module
, MonoString
*name
, MonoBoolean throwOnError
, MonoBoolean ignoreCase
)
4226 MonoType
*type
= NULL
;
4227 MonoTypeNameParse info
;
4228 gboolean type_resolve
;
4230 MONO_ARCH_SAVE_REGS
;
4232 /* On MS.NET, this does not fire a TypeResolve event */
4233 type_resolve
= TRUE
;
4234 str
= mono_string_to_utf8 (name
);
4235 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4236 if (!mono_reflection_parse_type (str
, &info
)) {
4238 mono_reflection_free_type_info (&info
);
4239 if (throwOnError
) /* uhm: this is a parse error, though... */
4240 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4241 /*g_print ("failed parse\n");*/
4245 if (info
.assembly
.name
) {
4247 mono_reflection_free_type_info (&info
);
4249 /* 1.0 and 2.0 throw different exceptions */
4250 if (mono_defaults
.generic_ilist_class
)
4251 mono_raise_exception (mono_get_exception_argument (NULL
, "Type names passed to Assembly.GetType() must not specify an assembly."));
4253 mono_raise_exception (mono_get_exception_type_load (name
, NULL
));
4258 if (module
!= NULL
) {
4260 type
= mono_reflection_get_type (module
->image
, &info
, ignoreCase
, &type_resolve
);
4265 if (assembly
->assembly
->dynamic
) {
4266 /* Enumerate all modules */
4267 MonoReflectionAssemblyBuilder
*abuilder
= (MonoReflectionAssemblyBuilder
*)assembly
;
4271 if (abuilder
->modules
) {
4272 for (i
= 0; i
< mono_array_length (abuilder
->modules
); ++i
) {
4273 MonoReflectionModuleBuilder
*mb
= mono_array_get (abuilder
->modules
, MonoReflectionModuleBuilder
*, i
);
4274 type
= mono_reflection_get_type (&mb
->dynamic_image
->image
, &info
, ignoreCase
, &type_resolve
);
4280 if (!type
&& abuilder
->loaded_modules
) {
4281 for (i
= 0; i
< mono_array_length (abuilder
->loaded_modules
); ++i
) {
4282 MonoReflectionModule
*mod
= mono_array_get (abuilder
->loaded_modules
, MonoReflectionModule
*, i
);
4283 type
= mono_reflection_get_type (mod
->image
, &info
, ignoreCase
, &type_resolve
);
4290 type
= mono_reflection_get_type (assembly
->assembly
->image
, &info
, ignoreCase
, &type_resolve
);
4292 mono_reflection_free_type_info (&info
);
4294 MonoException
*e
= NULL
;
4297 e
= mono_get_exception_type_load (name
, NULL
);
4299 mono_loader_clear_error ();
4302 mono_raise_exception (e
);
4307 if (type
->type
== MONO_TYPE_CLASS
) {
4308 MonoClass
*klass
= mono_type_get_class (type
);
4310 if (mono_is_security_manager_active () && !klass
->exception_type
)
4311 /* Some security problems are detected during generic vtable construction */
4312 mono_class_setup_vtable (klass
);
4313 /* need to report exceptions ? */
4314 if (throwOnError
&& klass
->exception_type
) {
4315 /* report SecurityException (or others) that occured when loading the assembly */
4316 MonoException
*exc
= mono_class_get_exception_for_failure (klass
);
4317 mono_loader_clear_error ();
4318 mono_raise_exception (exc
);
4319 } else if (klass
->exception_type
== MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND
) {
4324 /* g_print ("got it\n"); */
4325 return mono_type_get_object (mono_object_domain (assembly
), type
);
4329 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly
*assembly
, MonoBoolean escaped
)
4331 MonoDomain
*domain
= mono_object_domain (assembly
);
4332 MonoAssembly
*mass
= assembly
->assembly
;
4333 MonoString
*res
= NULL
;
4337 gchar
*shadow_ini_file
;
4341 MONO_ARCH_SAVE_REGS
;
4343 if (g_path_is_absolute (mass
->image
->name
)) {
4344 absolute
= g_strdup (mass
->image
->name
);
4345 dirname
= g_path_get_dirname (absolute
);
4347 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
4348 dirname
= g_strdup (mass
->basedir
);
4351 /* Check for shadow-copied assembly */
4352 if (mono_is_shadow_copy_enabled (domain
, dirname
)) {
4353 shadow_ini_file
= g_build_filename (dirname
, "__AssemblyInfo__.ini", NULL
);
4355 if (!g_file_get_contents (shadow_ini_file
, &content
, &len
, NULL
) ||
4356 !g_file_test (content
, G_FILE_TEST_IS_REGULAR
)) {
4362 g_free (shadow_ini_file
);
4363 if (content
!= NULL
) {
4373 for (i
= strlen (absolute
) - 1; i
>= 0; i
--)
4374 if (absolute
[i
] == '\\')
4379 uri
= g_filename_to_uri (absolute
, NULL
, NULL
);
4381 const char *prepend
= "file://";
4383 if (*absolute
== '/' && *(absolute
+ 1) == '/') {
4386 prepend
= "file:///";
4389 uri
= g_strconcat (prepend
, absolute
, NULL
);
4393 res
= mono_string_new (domain
, uri
);
4401 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly
*assembly
)
4403 MonoAssembly
*mass
= assembly
->assembly
;
4405 MONO_ARCH_SAVE_REGS
;
4407 return mass
->in_gac
;
4410 static MonoReflectionAssembly
*
4411 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString
*mname
, MonoObject
*evidence
)
4415 MonoImageOpenStatus status
;
4417 MONO_ARCH_SAVE_REGS
;
4419 name
= mono_string_to_utf8 (mname
);
4420 res
= mono_assembly_load_with_partial_name (name
, &status
);
4426 return mono_assembly_get_object (mono_domain_get (), res
);
4430 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly
*assembly
)
4432 MonoDomain
*domain
= mono_object_domain (assembly
);
4435 MONO_ARCH_SAVE_REGS
;
4437 res
= mono_string_new (domain
, mono_image_get_filename (assembly
->assembly
->image
));
4443 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
*assembly
)
4445 MONO_ARCH_SAVE_REGS
;
4447 return assembly
->assembly
->ref_only
;
4451 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly
*assembly
)
4453 MonoDomain
*domain
= mono_object_domain (assembly
);
4455 MONO_ARCH_SAVE_REGS
;
4457 return mono_string_new (domain
, assembly
->assembly
->image
->version
);
4460 static MonoReflectionMethod
*
4461 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly
*assembly
)
4463 guint32 token
= mono_image_get_entry_point (assembly
->assembly
->image
);
4465 MONO_ARCH_SAVE_REGS
;
4469 return mono_method_get_object (mono_object_domain (assembly
), mono_get_method (assembly
->assembly
->image
, token
, NULL
), NULL
);
4472 static MonoReflectionModule
*
4473 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly
*assembly
)
4475 return mono_module_get_object (mono_object_domain (assembly
), assembly
->assembly
->image
);
4479 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly
*assembly
)
4481 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4482 MonoArray
*result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, table
->rows
);
4486 MONO_ARCH_SAVE_REGS
;
4488 for (i
= 0; i
< table
->rows
; ++i
) {
4489 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_MANIFEST_NAME
));
4490 mono_array_setref (result
, i
, mono_string_new (mono_object_domain (assembly
), val
));
4496 create_version (MonoDomain
*domain
, guint32 major
, guint32 minor
, guint32 build
, guint32 revision
)
4498 static MonoClass
*System_Version
= NULL
;
4499 static MonoMethod
*create_version
= NULL
;
4503 if (!System_Version
) {
4504 System_Version
= mono_class_from_name (mono_defaults
.corlib
, "System", "Version");
4505 g_assert (System_Version
);
4508 if (!create_version
) {
4509 MonoMethodDesc
*desc
= mono_method_desc_new (":.ctor(int,int,int,int)", FALSE
);
4510 create_version
= mono_method_desc_search_in_class (desc
, System_Version
);
4511 g_assert (create_version
);
4512 mono_method_desc_free (desc
);
4518 args
[3] = &revision
;
4519 result
= mono_object_new (domain
, System_Version
);
4520 mono_runtime_invoke (create_version
, result
, args
, NULL
);
4526 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly
*assembly
)
4528 static MonoClass
*System_Reflection_AssemblyName
;
4530 MonoDomain
*domain
= mono_object_domain (assembly
);
4532 static MonoMethod
*create_culture
= NULL
;
4533 MonoImage
*image
= assembly
->assembly
->image
;
4536 MONO_ARCH_SAVE_REGS
;
4538 if (!System_Reflection_AssemblyName
)
4539 System_Reflection_AssemblyName
= mono_class_from_name (
4540 mono_defaults
.corlib
, "System.Reflection", "AssemblyName");
4542 t
= &assembly
->assembly
->image
->tables
[MONO_TABLE_ASSEMBLYREF
];
4545 result
= mono_array_new (domain
, System_Reflection_AssemblyName
, count
);
4548 MonoMethodDesc
*desc
= mono_method_desc_new (
4549 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
4550 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
4551 g_assert (create_culture
);
4552 mono_method_desc_free (desc
);
4555 for (i
= 0; i
< count
; i
++) {
4556 MonoReflectionAssemblyName
*aname
;
4557 guint32 cols
[MONO_ASSEMBLYREF_SIZE
];
4559 mono_metadata_decode_row (t
, i
, cols
, MONO_ASSEMBLYREF_SIZE
);
4561 aname
= (MonoReflectionAssemblyName
*) mono_object_new (
4562 domain
, System_Reflection_AssemblyName
);
4564 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_NAME
])));
4566 aname
->major
= cols
[MONO_ASSEMBLYREF_MAJOR_VERSION
];
4567 aname
->minor
= cols
[MONO_ASSEMBLYREF_MINOR_VERSION
];
4568 aname
->build
= cols
[MONO_ASSEMBLYREF_BUILD_NUMBER
];
4569 aname
->revision
= cols
[MONO_ASSEMBLYREF_REV_NUMBER
];
4570 aname
->flags
= cols
[MONO_ASSEMBLYREF_FLAGS
];
4571 aname
->versioncompat
= 1; /* SameMachine (default) */
4572 aname
->hashalg
= ASSEMBLY_HASH_SHA1
; /* SHA1 (default) */
4573 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, aname
->major
, aname
->minor
, aname
->build
, aname
->revision
));
4575 if (create_culture
) {
4577 MonoBoolean assembly_ref
= 1;
4578 args
[0] = mono_string_new (domain
, mono_metadata_string_heap (image
, cols
[MONO_ASSEMBLYREF_CULTURE
]));
4579 args
[1] = &assembly_ref
;
4580 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
4583 if (cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]) {
4584 const gchar
*pkey_ptr
= mono_metadata_blob_heap (image
, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY
]);
4585 guint32 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
4587 if ((cols
[MONO_ASSEMBLYREF_FLAGS
] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
)) {
4588 /* public key token isn't copied - the class library will
4589 automatically generate it from the public key if required */
4590 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4591 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
4593 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
4594 memcpy (mono_array_addr (aname
->keyToken
, guint8
, 0), pkey_ptr
, pkey_len
);
4597 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
4600 /* note: this function doesn't return the codebase on purpose (i.e. it can
4601 be used under partial trust as path information isn't present). */
4603 mono_array_setref (result
, i
, aname
);
4614 foreach_namespace (const char* key
, gconstpointer val
, NameSpaceInfo
*info
)
4616 MonoString
*name
= mono_string_new (mono_object_domain (info
->res
), key
);
4618 mono_array_setref (info
->res
, info
->idx
, name
);
4623 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly
*assembly
)
4625 MonoImage
*img
= assembly
->assembly
->image
;
4629 MONO_ARCH_SAVE_REGS
;
4631 if (!img
->name_cache
)
4632 mono_image_init_name_cache (img
);
4634 res
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, g_hash_table_size (img
->name_cache
));
4637 g_hash_table_foreach (img
->name_cache
, (GHFunc
)foreach_namespace
, &info
);
4642 /* move this in some file in mono/util/ */
4644 g_concat_dir_and_file (const char *dir
, const char *file
)
4646 g_return_val_if_fail (dir
!= NULL
, NULL
);
4647 g_return_val_if_fail (file
!= NULL
, NULL
);
4650 * If the directory name doesn't have a / on the end, we need
4651 * to add one so we get a proper path to the file
4653 if (dir
[strlen(dir
) - 1] != G_DIR_SEPARATOR
)
4654 return g_strconcat (dir
, G_DIR_SEPARATOR_S
, file
, NULL
);
4656 return g_strconcat (dir
, file
, NULL
);
4660 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, gint32
*size
, MonoReflectionModule
**ref_module
)
4662 char *n
= mono_string_to_utf8 (name
);
4663 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4665 guint32 cols
[MONO_MANIFEST_SIZE
];
4666 guint32 impl
, file_idx
;
4670 MONO_ARCH_SAVE_REGS
;
4672 for (i
= 0; i
< table
->rows
; ++i
) {
4673 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4674 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4675 if (strcmp (val
, n
) == 0)
4679 if (i
== table
->rows
)
4682 impl
= cols
[MONO_MANIFEST_IMPLEMENTATION
];
4685 * this code should only be called after obtaining the
4686 * ResourceInfo and handling the other cases.
4688 g_assert ((impl
& MONO_IMPLEMENTATION_MASK
) == MONO_IMPLEMENTATION_FILE
);
4689 file_idx
= impl
>> MONO_IMPLEMENTATION_BITS
;
4691 module
= mono_image_load_file_for_image (assembly
->assembly
->image
, file_idx
);
4696 module
= assembly
->assembly
->image
;
4698 *ref_module
= mono_module_get_object (mono_domain_get (), module
);
4700 return (void*)mono_image_get_resource (module
, cols
[MONO_MANIFEST_OFFSET
], (guint32
*)size
);
4704 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoManifestResourceInfo
*info
)
4706 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_MANIFESTRESOURCE
];
4708 guint32 cols
[MONO_MANIFEST_SIZE
];
4709 guint32 file_cols
[MONO_FILE_SIZE
];
4713 MONO_ARCH_SAVE_REGS
;
4715 n
= mono_string_to_utf8 (name
);
4716 for (i
= 0; i
< table
->rows
; ++i
) {
4717 mono_metadata_decode_row (table
, i
, cols
, MONO_MANIFEST_SIZE
);
4718 val
= mono_metadata_string_heap (assembly
->assembly
->image
, cols
[MONO_MANIFEST_NAME
]);
4719 if (strcmp (val
, n
) == 0)
4723 if (i
== table
->rows
)
4726 if (!cols
[MONO_MANIFEST_IMPLEMENTATION
]) {
4727 info
->location
= RESOURCE_LOCATION_EMBEDDED
| RESOURCE_LOCATION_IN_MANIFEST
;
4730 switch (cols
[MONO_MANIFEST_IMPLEMENTATION
] & MONO_IMPLEMENTATION_MASK
) {
4731 case MONO_IMPLEMENTATION_FILE
:
4732 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4733 table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4734 mono_metadata_decode_row (table
, i
- 1, file_cols
, MONO_FILE_SIZE
);
4735 val
= mono_metadata_string_heap (assembly
->assembly
->image
, file_cols
[MONO_FILE_NAME
]);
4736 MONO_OBJECT_SETREF (info
, filename
, mono_string_new (mono_object_domain (assembly
), val
));
4737 if (file_cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4740 info
->location
= RESOURCE_LOCATION_EMBEDDED
;
4743 case MONO_IMPLEMENTATION_ASSEMBLYREF
:
4744 i
= cols
[MONO_MANIFEST_IMPLEMENTATION
] >> MONO_IMPLEMENTATION_BITS
;
4745 mono_assembly_load_reference (assembly
->assembly
->image
, i
- 1);
4746 if (assembly
->assembly
->image
->references
[i
- 1] == (gpointer
)-1) {
4747 char *msg
= g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i
- 1, assembly
->assembly
->image
->name
);
4748 MonoException
*ex
= mono_get_exception_file_not_found2 (msg
, NULL
);
4750 mono_raise_exception (ex
);
4752 MONO_OBJECT_SETREF (info
, assembly
, mono_assembly_get_object (mono_domain_get (), assembly
->assembly
->image
->references
[i
- 1]));
4754 /* Obtain info recursively */
4755 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info
->assembly
, name
, info
);
4756 info
->location
|= RESOURCE_LOCATION_ANOTHER_ASSEMBLY
;
4759 case MONO_IMPLEMENTATION_EXP_TYPE
:
4760 g_assert_not_reached ();
4769 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly
*assembly
, MonoString
*name
, MonoBoolean resource_modules
)
4771 MonoTableInfo
*table
= &assembly
->assembly
->image
->tables
[MONO_TABLE_FILE
];
4772 MonoArray
*result
= NULL
;
4777 MONO_ARCH_SAVE_REGS
;
4779 /* check hash if needed */
4781 n
= mono_string_to_utf8 (name
);
4782 for (i
= 0; i
< table
->rows
; ++i
) {
4783 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4784 if (strcmp (val
, n
) == 0) {
4787 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4788 fn
= mono_string_new (mono_object_domain (assembly
), n
);
4790 return (MonoObject
*)fn
;
4798 for (i
= 0; i
< table
->rows
; ++i
) {
4799 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
))
4803 result
= mono_array_new (mono_object_domain (assembly
), mono_defaults
.string_class
, count
);
4806 for (i
= 0; i
< table
->rows
; ++i
) {
4807 if (resource_modules
|| !(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
4808 val
= mono_metadata_string_heap (assembly
->assembly
->image
, mono_metadata_decode_row_col (table
, i
, MONO_FILE_NAME
));
4809 n
= g_concat_dir_and_file (assembly
->assembly
->basedir
, val
);
4810 mono_array_setref (result
, count
, mono_string_new (mono_object_domain (assembly
), n
));
4815 return (MonoObject
*)result
;
4819 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
*assembly
)
4821 MonoDomain
*domain
= mono_domain_get();
4824 int i
, j
, file_count
= 0;
4825 MonoImage
**modules
;
4826 guint32 module_count
, real_module_count
;
4827 MonoTableInfo
*table
;
4828 guint32 cols
[MONO_FILE_SIZE
];
4829 MonoImage
*image
= assembly
->assembly
->image
;
4831 g_assert (image
!= NULL
);
4832 g_assert (!assembly
->assembly
->dynamic
);
4834 table
= &image
->tables
[MONO_TABLE_FILE
];
4835 file_count
= table
->rows
;
4837 modules
= image
->modules
;
4838 module_count
= image
->module_count
;
4840 real_module_count
= 0;
4841 for (i
= 0; i
< module_count
; ++i
)
4843 real_module_count
++;
4845 klass
= mono_class_from_name (mono_defaults
.corlib
, "System.Reflection", "Module");
4846 res
= mono_array_new (domain
, klass
, 1 + real_module_count
+ file_count
);
4848 mono_array_setref (res
, 0, mono_module_get_object (domain
, image
));
4850 for (i
= 0; i
< module_count
; ++i
)
4852 mono_array_setref (res
, j
, mono_module_get_object (domain
, modules
[i
]));
4856 for (i
= 0; i
< file_count
; ++i
, ++j
) {
4857 mono_metadata_decode_row (table
, i
, cols
, MONO_FILE_SIZE
);
4858 if (cols
[MONO_FILE_FLAGS
] && FILE_CONTAINS_NO_METADATA
)
4859 mono_array_setref (res
, j
, mono_module_file_get_object (domain
, image
, i
));
4861 MonoImage
*m
= mono_image_load_file_for_image (image
, i
+ 1);
4863 MonoString
*fname
= mono_string_new (mono_domain_get (), mono_metadata_string_heap (image
, cols
[MONO_FILE_NAME
]));
4864 mono_raise_exception (mono_get_exception_file_not_found2 (NULL
, fname
));
4866 mono_array_setref (res
, j
, mono_module_get_object (domain
, m
));
4873 static MonoReflectionMethod
*
4874 ves_icall_GetCurrentMethod (void)
4876 MonoMethod
*m
= mono_method_get_last_managed ();
4878 MONO_ARCH_SAVE_REGS
;
4880 return mono_method_get_object (mono_domain_get (), m
, NULL
);
4885 mono_method_get_equivalent_method (MonoMethod
*method
, MonoClass
*klass
)
4888 if (method
->is_inflated
&& ((MonoMethodInflated
*)method
)->context
.method_inst
) {
4889 MonoMethodInflated
*inflated
= (MonoMethodInflated
*)method
;
4890 //method is inflated, we should inflate it on the other class
4891 MonoGenericContext ctx
;
4892 ctx
.method_inst
= inflated
->context
.method_inst
;
4893 ctx
.class_inst
= inflated
->context
.class_inst
;
4894 if (klass
->generic_class
)
4895 ctx
.class_inst
= klass
->generic_class
->context
.class_inst
;
4896 else if (klass
->generic_container
)
4897 ctx
.class_inst
= klass
->generic_container
->context
.class_inst
;
4898 return mono_class_inflate_generic_method_full (inflated
->declaring
, klass
, &ctx
);
4901 mono_class_setup_methods (method
->klass
);
4902 for (i
= 0; i
< method
->klass
->method
.count
; ++i
) {
4903 if (method
->klass
->methods
[i
] == method
) {
4908 mono_class_setup_methods (klass
);
4909 g_assert (offset
>= 0 && offset
< klass
->method
.count
);
4910 return klass
->methods
[offset
];
4913 static MonoReflectionMethod
*
4914 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod
*method
, MonoType
*type
)
4918 klass
= mono_class_from_mono_type (type
);
4919 if (mono_class_get_generic_type_definition (method
->klass
) != mono_class_get_generic_type_definition (klass
))
4921 if (method
->klass
!= klass
)
4922 method
= mono_method_get_equivalent_method (method
, klass
);
4924 klass
= method
->klass
;
4925 return mono_method_get_object (mono_domain_get (), method
, klass
);
4928 static MonoReflectionMethod
*
4929 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod
*method
)
4931 return mono_method_get_object (mono_domain_get (), method
, NULL
);
4934 static MonoReflectionMethodBody
*
4935 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod
*method
)
4937 return mono_method_body_get_object (mono_domain_get (), method
);
4940 static MonoReflectionAssembly
*
4941 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4943 MonoMethod
*dest
= NULL
;
4945 MONO_ARCH_SAVE_REGS
;
4947 mono_stack_walk_no_il (get_executing
, &dest
);
4948 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4952 static MonoReflectionAssembly
*
4953 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4955 MonoDomain
* domain
= mono_domain_get ();
4957 MONO_ARCH_SAVE_REGS
;
4959 if (!domain
->entry_assembly
)
4962 return mono_assembly_get_object (domain
, domain
->entry_assembly
);
4965 static MonoReflectionAssembly
*
4966 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4971 MONO_ARCH_SAVE_REGS
;
4974 mono_stack_walk_no_il (get_executing
, &dest
);
4976 mono_stack_walk_no_il (get_caller
, &dest
);
4979 return mono_assembly_get_object (mono_domain_get (), dest
->klass
->image
->assembly
);
4983 ves_icall_System_MonoType_getFullName (MonoReflectionType
*object
, gboolean full_name
,
4984 gboolean assembly_qualified
)
4986 MonoDomain
*domain
= mono_object_domain (object
);
4987 MonoTypeNameFormat format
;
4991 MONO_ARCH_SAVE_REGS
;
4993 format
= assembly_qualified
?
4994 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED
:
4995 MONO_TYPE_NAME_FORMAT_FULL_NAME
;
4997 format
= MONO_TYPE_NAME_FORMAT_REFLECTION
;
4999 name
= mono_type_get_name_full (object
->type
, format
);
5003 if (full_name
&& (object
->type
->type
== MONO_TYPE_VAR
|| object
->type
->type
== MONO_TYPE_MVAR
)) {
5008 res
= mono_string_new (domain
, name
);
5015 fill_reflection_assembly_name (MonoDomain
*domain
, MonoReflectionAssemblyName
*aname
, MonoAssemblyName
*name
, const char *absolute
, gboolean by_default_version
, gboolean default_publickey
, gboolean default_token
)
5017 static MonoMethod
*create_culture
= NULL
;
5020 const char *pkey_ptr
;
5022 MonoBoolean assembly_ref
= 0;
5024 MONO_ARCH_SAVE_REGS
;
5026 MONO_OBJECT_SETREF (aname
, name
, mono_string_new (domain
, name
->name
));
5027 aname
->major
= name
->major
;
5028 aname
->minor
= name
->minor
;
5029 aname
->build
= name
->build
;
5030 aname
->flags
= name
->flags
;
5031 aname
->revision
= name
->revision
;
5032 aname
->hashalg
= name
->hash_alg
;
5033 aname
->versioncompat
= 1; /* SameMachine (default) */
5035 if (by_default_version
)
5036 MONO_OBJECT_SETREF (aname
, version
, create_version (domain
, name
->major
, name
->minor
, name
->build
, name
->revision
));
5039 if (absolute
!= NULL
&& *absolute
!= '\0') {
5040 const gchar
*prepend
= "file://";
5043 codebase
= g_strdup (absolute
);
5048 for (i
= strlen (codebase
) - 1; i
>= 0; i
--)
5049 if (codebase
[i
] == '\\')
5052 if (*codebase
== '/' && *(codebase
+ 1) == '/') {
5055 prepend
= "file:///";
5059 result
= g_strconcat (prepend
, codebase
, NULL
);
5065 MONO_OBJECT_SETREF (aname
, codebase
, mono_string_new (domain
, codebase
));
5069 if (!create_culture
) {
5070 MonoMethodDesc
*desc
= mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE
);
5071 create_culture
= mono_method_desc_search_in_image (desc
, mono_defaults
.corlib
);
5072 g_assert (create_culture
);
5073 mono_method_desc_free (desc
);
5076 if (name
->culture
) {
5077 args
[0] = mono_string_new (domain
, name
->culture
);
5078 args
[1] = &assembly_ref
;
5079 MONO_OBJECT_SETREF (aname
, cultureInfo
, mono_runtime_invoke (create_culture
, NULL
, args
, NULL
));
5082 if (name
->public_key
) {
5083 pkey_ptr
= (char*)name
->public_key
;
5084 pkey_len
= mono_metadata_decode_blob_size (pkey_ptr
, &pkey_ptr
);
5086 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, pkey_len
));
5087 memcpy (mono_array_addr (aname
->publicKey
, guint8
, 0), pkey_ptr
, pkey_len
);
5088 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
5089 } else if (default_publickey
) {
5090 MONO_OBJECT_SETREF (aname
, publicKey
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
5091 aname
->flags
|= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG
;
5094 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5095 if (name
->public_key_token
[0]) {
5099 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 8));
5100 p
= mono_array_addr (aname
->keyToken
, char, 0);
5102 for (i
= 0, j
= 0; i
< 8; i
++) {
5103 *p
= g_ascii_xdigit_value (name
->public_key_token
[j
++]) << 4;
5104 *p
|= g_ascii_xdigit_value (name
->public_key_token
[j
++]);
5107 } else if (default_token
) {
5108 MONO_OBJECT_SETREF (aname
, keyToken
, mono_array_new (domain
, mono_defaults
.byte_class
, 0));
5113 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly
*assembly
)
5115 MonoDomain
*domain
= mono_object_domain (assembly
);
5116 MonoAssembly
*mass
= assembly
->assembly
;
5120 name
= g_strdup_printf (
5121 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
5123 mass
->aname
.major
, mass
->aname
.minor
, mass
->aname
.build
, mass
->aname
.revision
,
5124 mass
->aname
.culture
&& *mass
->aname
.culture
? mass
->aname
.culture
: "neutral",
5125 mass
->aname
.public_key_token
[0] ? (char *)mass
->aname
.public_key_token
: "null",
5126 (mass
->aname
.flags
& ASSEMBLYREF_RETARGETABLE_FLAG
) ? ", Retargetable=Yes" : "");
5128 res
= mono_string_new (domain
, name
);
5135 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly
*assembly
, MonoReflectionAssemblyName
*aname
)
5138 MonoAssembly
*mass
= assembly
->assembly
;
5140 MONO_ARCH_SAVE_REGS
;
5142 if (g_path_is_absolute (mass
->image
->name
)) {
5143 fill_reflection_assembly_name (mono_object_domain (assembly
),
5144 aname
, &mass
->aname
, mass
->image
->name
, TRUE
,
5145 TRUE
, mono_framework_version () >= 2);
5148 absolute
= g_build_filename (mass
->basedir
, mass
->image
->name
, NULL
);
5150 fill_reflection_assembly_name (mono_object_domain (assembly
),
5151 aname
, &mass
->aname
, absolute
, TRUE
, TRUE
,
5152 mono_framework_version () >= 2);
5158 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString
*fname
, MonoReflectionAssemblyName
*aname
)
5161 MonoImageOpenStatus status
= MONO_IMAGE_OK
;
5164 MonoAssemblyName name
;
5166 MONO_ARCH_SAVE_REGS
;
5168 filename
= mono_string_to_utf8 (fname
);
5170 image
= mono_image_open (filename
, &status
);
5176 if (status
== MONO_IMAGE_IMAGE_INVALID
)
5177 exc
= mono_get_exception_bad_image_format2 (NULL
, fname
);
5179 exc
= mono_get_exception_file_not_found2 (NULL
, fname
);
5180 mono_raise_exception (exc
);
5183 res
= mono_assembly_fill_assembly_name (image
, &name
);
5185 mono_image_close (image
);
5187 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5190 fill_reflection_assembly_name (mono_domain_get (), aname
, &name
, filename
,
5191 TRUE
, mono_framework_version () == 1,
5192 mono_framework_version () >= 2);
5195 mono_image_close (image
);
5199 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly
*assembly
,
5200 char **minimum
, guint32
*minLength
, char **optional
, guint32
*optLength
, char **refused
, guint32
*refLength
)
5202 MonoBoolean result
= FALSE
;
5203 MonoDeclSecurityEntry entry
;
5205 /* SecurityAction.RequestMinimum */
5206 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQMIN
, &entry
)) {
5207 *minimum
= entry
.blob
;
5208 *minLength
= entry
.size
;
5211 /* SecurityAction.RequestOptional */
5212 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQOPT
, &entry
)) {
5213 *optional
= entry
.blob
;
5214 *optLength
= entry
.size
;
5217 /* SecurityAction.RequestRefuse */
5218 if (mono_declsec_get_assembly_action (assembly
->assembly
, SECURITY_ACTION_REQREFUSE
, &entry
)) {
5219 *refused
= entry
.blob
;
5220 *refLength
= entry
.size
;
5228 mono_module_get_types (MonoDomain
*domain
, MonoImage
*image
, MonoArray
**exceptions
, MonoBoolean exportedOnly
)
5232 MonoTableInfo
*tdef
= &image
->tables
[MONO_TABLE_TYPEDEF
];
5234 guint32 attrs
, visibility
;
5236 /* we start the count from 1 because we skip the special type <Module> */
5239 for (i
= 1; i
< tdef
->rows
; ++i
) {
5240 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5241 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5242 if (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)
5246 count
= tdef
->rows
- 1;
5248 res
= mono_array_new (domain
, mono_defaults
.monotype_class
, count
);
5249 *exceptions
= mono_array_new (domain
, mono_defaults
.exception_class
, count
);
5251 for (i
= 1; i
< tdef
->rows
; ++i
) {
5252 attrs
= mono_metadata_decode_row_col (tdef
, i
, MONO_TYPEDEF_FLAGS
);
5253 visibility
= attrs
& TYPE_ATTRIBUTE_VISIBILITY_MASK
;
5254 if (!exportedOnly
|| (visibility
== TYPE_ATTRIBUTE_PUBLIC
|| visibility
== TYPE_ATTRIBUTE_NESTED_PUBLIC
)) {
5255 klass
= mono_class_get (image
, (i
+ 1) | MONO_TOKEN_TYPE_DEF
);
5257 mono_array_setref (res
, count
, mono_type_get_object (domain
, &klass
->byval_arg
));
5259 MonoLoaderError
*error
;
5262 error
= mono_loader_get_last_error ();
5263 g_assert (error
!= NULL
);
5265 ex
= mono_loader_error_prepare_exception (error
);
5266 mono_array_setref (*exceptions
, count
, ex
);
5268 if (mono_loader_get_last_error ())
5269 mono_loader_clear_error ();
5278 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly
*assembly
, MonoBoolean exportedOnly
)
5280 MonoArray
*res
= NULL
;
5281 MonoArray
*exceptions
= NULL
;
5282 MonoImage
*image
= NULL
;
5283 MonoTableInfo
*table
= NULL
;
5286 int i
, len
, ex_count
;
5288 MONO_ARCH_SAVE_REGS
;
5290 domain
= mono_object_domain (assembly
);
5292 g_assert (!assembly
->assembly
->dynamic
);
5293 image
= assembly
->assembly
->image
;
5294 table
= &image
->tables
[MONO_TABLE_FILE
];
5295 res
= mono_module_get_types (domain
, image
, &exceptions
, exportedOnly
);
5297 /* Append data from all modules in the assembly */
5298 for (i
= 0; i
< table
->rows
; ++i
) {
5299 if (!(mono_metadata_decode_row_col (table
, i
, MONO_FILE_FLAGS
) & FILE_CONTAINS_NO_METADATA
)) {
5300 MonoImage
*loaded_image
= mono_assembly_load_module (image
->assembly
, i
+ 1);
5303 MonoArray
*res2
= mono_module_get_types (domain
, loaded_image
, &ex2
, exportedOnly
);
5304 /* Append the new types to the end of the array */
5305 if (mono_array_length (res2
) > 0) {
5307 MonoArray
*res3
, *ex3
;
5309 len1
= mono_array_length (res
);
5310 len2
= mono_array_length (res2
);
5312 res3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5313 mono_array_memcpy_refs (res3
, 0, res
, 0, len1
);
5314 mono_array_memcpy_refs (res3
, len1
, res2
, 0, len2
);
5317 ex3
= mono_array_new (domain
, mono_defaults
.monotype_class
, len1
+ len2
);
5318 mono_array_memcpy_refs (ex3
, 0, exceptions
, 0, len1
);
5319 mono_array_memcpy_refs (ex3
, len1
, ex2
, 0, len2
);
5326 /* the ReflectionTypeLoadException must have all the types (Types property),
5327 * NULL replacing types which throws an exception. The LoaderException must
5328 * contain all exceptions for NULL items.
5331 len
= mono_array_length (res
);
5334 for (i
= 0; i
< len
; i
++) {
5335 MonoReflectionType
*t
= mono_array_get (res
, gpointer
, i
);
5339 klass
= mono_type_get_class (t
->type
);
5340 if ((klass
!= NULL
) && klass
->exception_type
) {
5341 /* keep the class in the list */
5342 list
= g_list_append (list
, klass
);
5343 /* and replace Type with NULL */
5344 mono_array_setref (res
, i
, NULL
);
5351 if (list
|| ex_count
) {
5353 MonoException
*exc
= NULL
;
5354 MonoArray
*exl
= NULL
;
5355 int j
, length
= g_list_length (list
) + ex_count
;
5357 mono_loader_clear_error ();
5359 exl
= mono_array_new (domain
, mono_defaults
.exception_class
, length
);
5360 /* Types for which mono_class_get () succeeded */
5361 for (i
= 0, tmp
= list
; tmp
; i
++, tmp
= tmp
->next
) {
5362 MonoException
*exc
= mono_class_get_exception_for_failure (tmp
->data
);
5363 mono_array_setref (exl
, i
, exc
);
5365 /* Types for which it don't */
5366 for (j
= 0; j
< mono_array_length (exceptions
); ++j
) {
5367 MonoException
*exc
= mono_array_get (exceptions
, MonoException
*, j
);
5369 g_assert (i
< length
);
5370 mono_array_setref (exl
, i
, exc
);
5377 exc
= mono_get_exception_reflection_type_load (res
, exl
);
5378 mono_loader_clear_error ();
5379 mono_raise_exception (exc
);
5386 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName
*name
, MonoString
*assname
)
5388 MonoAssemblyName aname
;
5389 MonoDomain
*domain
= mono_object_domain (name
);
5391 gboolean is_version_defined
;
5392 gboolean is_token_defined
;
5394 aname
.public_key
= NULL
;
5395 val
= mono_string_to_utf8 (assname
);
5396 if (!mono_assembly_name_parse_full (val
, &aname
, TRUE
, &is_version_defined
, &is_token_defined
)) {
5397 g_free ((guint8
*) aname
.public_key
);
5402 fill_reflection_assembly_name (domain
, name
, &aname
, "", is_version_defined
,
5403 FALSE
, is_token_defined
);
5405 mono_assembly_name_free (&aname
);
5406 g_free ((guint8
*) aname
.public_key
);
5412 static MonoReflectionType
*
5413 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule
*module
)
5415 MonoDomain
*domain
= mono_object_domain (module
);
5418 MONO_ARCH_SAVE_REGS
;
5420 g_assert (module
->image
);
5422 if (module
->image
->dynamic
&& ((MonoDynamicImage
*)(module
->image
))->initial_image
)
5423 /* These images do not have a global type */
5426 klass
= mono_class_get (module
->image
, 1 | MONO_TOKEN_TYPE_DEF
);
5427 return mono_type_get_object (domain
, &klass
->byval_arg
);
5431 ves_icall_System_Reflection_Module_Close (MonoReflectionModule
*module
)
5433 /*if (module->image)
5434 mono_image_close (module->image);*/
5438 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule
*module
)
5440 MonoDomain
*domain
= mono_object_domain (module
);
5442 MONO_ARCH_SAVE_REGS
;
5444 g_assert (module
->image
);
5445 return mono_string_new (domain
, module
->image
->guid
);
5449 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule
*module
)
5451 #ifdef PLATFORM_WIN32
5452 if (module
->image
&& module
->image
->is_module_handle
)
5453 return module
->image
->raw_data
;
5456 return (gpointer
) (-1);
5460 ves_icall_System_Reflection_Module_GetPEKind (MonoImage
*image
, gint32
*pe_kind
, gint32
*machine
)
5462 if (image
->dynamic
) {
5463 MonoDynamicImage
*dyn
= (MonoDynamicImage
*)image
;
5464 *pe_kind
= dyn
->pe_kind
;
5465 *machine
= dyn
->machine
;
5468 *pe_kind
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_cli_header
.ch_flags
& 0x3;
5469 *machine
= ((MonoCLIImageInfo
*)(image
->image_info
))->cli_header
.coff
.coff_machine
;
5474 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage
*image
)
5476 return (image
->md_version_major
<< 16) | (image
->md_version_minor
);
5480 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule
*module
)
5482 MonoArray
*exceptions
;
5485 MONO_ARCH_SAVE_REGS
;
5488 return mono_array_new (mono_object_domain (module
), mono_defaults
.monotype_class
, 0);
5490 MonoArray
*res
= mono_module_get_types (mono_object_domain (module
), module
->image
, &exceptions
, FALSE
);
5491 for (i
= 0; i
< mono_array_length (exceptions
); ++i
) {
5492 MonoException
*ex
= mono_array_get (exceptions
, MonoException
*, i
);
5494 mono_raise_exception (ex
);
5501 mono_metadata_memberref_is_method (MonoImage
*image
, guint32 token
)
5503 guint32 cols
[MONO_MEMBERREF_SIZE
];
5505 mono_metadata_decode_row (&image
->tables
[MONO_TABLE_MEMBERREF
], mono_metadata_token_index (token
) - 1, cols
, MONO_MEMBERREF_SIZE
);
5506 sig
= mono_metadata_blob_heap (image
, cols
[MONO_MEMBERREF_SIGNATURE
]);
5507 mono_metadata_decode_blob_size (sig
, &sig
);
5508 return (*sig
!= 0x6);
5512 init_generic_context_from_args (MonoGenericContext
*context
, MonoArray
*type_args
, MonoArray
*method_args
)
5515 context
->class_inst
= mono_metadata_get_generic_inst (mono_array_length (type_args
),
5516 mono_array_addr (type_args
, MonoType
*, 0));
5518 context
->class_inst
= NULL
;
5520 context
->method_inst
= mono_metadata_get_generic_inst (mono_array_length (method_args
),
5521 mono_array_addr (method_args
, MonoType
*, 0));
5523 context
->method_inst
= NULL
;
5527 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5530 int table
= mono_metadata_token_table (token
);
5531 int index
= mono_metadata_token_index (token
);
5532 MonoGenericContext context
;
5534 *error
= ResolveTokenError_Other
;
5536 /* Validate token */
5537 if ((table
!= MONO_TABLE_TYPEDEF
) && (table
!= MONO_TABLE_TYPEREF
) &&
5538 (table
!= MONO_TABLE_TYPESPEC
)) {
5539 *error
= ResolveTokenError_BadTable
;
5543 if (image
->dynamic
) {
5544 if (type_args
|| method_args
)
5545 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5546 klass
= mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5549 return &klass
->byval_arg
;
5552 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5553 *error
= ResolveTokenError_OutOfRange
;
5557 init_generic_context_from_args (&context
, type_args
, method_args
);
5558 klass
= mono_class_get_full (image
, token
, &context
);
5560 if (mono_loader_get_last_error ())
5561 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5564 return &klass
->byval_arg
;
5570 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5572 int table
= mono_metadata_token_table (token
);
5573 int index
= mono_metadata_token_index (token
);
5574 MonoGenericContext context
;
5577 *error
= ResolveTokenError_Other
;
5579 /* Validate token */
5580 if ((table
!= MONO_TABLE_METHOD
) && (table
!= MONO_TABLE_METHODSPEC
) &&
5581 (table
!= MONO_TABLE_MEMBERREF
)) {
5582 *error
= ResolveTokenError_BadTable
;
5586 if (image
->dynamic
) {
5587 if (type_args
|| method_args
)
5588 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5589 /* FIXME: validate memberref token type */
5590 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5593 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5594 *error
= ResolveTokenError_OutOfRange
;
5597 if ((table
== MONO_TABLE_MEMBERREF
) && (!mono_metadata_memberref_is_method (image
, token
))) {
5598 *error
= ResolveTokenError_BadTable
;
5602 init_generic_context_from_args (&context
, type_args
, method_args
);
5603 method
= mono_get_method_full (image
, token
, NULL
, &context
);
5605 if (mono_loader_get_last_error ())
5606 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5612 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5614 int index
= mono_metadata_token_index (token
);
5616 *error
= ResolveTokenError_Other
;
5618 /* Validate token */
5619 if (mono_metadata_token_code (token
) != MONO_TOKEN_STRING
) {
5620 *error
= ResolveTokenError_BadTable
;
5625 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5627 if ((index
<= 0) || (index
>= image
->heap_us
.size
)) {
5628 *error
= ResolveTokenError_OutOfRange
;
5632 /* FIXME: What to do if the index points into the middle of a string ? */
5634 return mono_ldstr (mono_domain_get (), image
, index
);
5637 static MonoClassField
*
5638 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5641 int table
= mono_metadata_token_table (token
);
5642 int index
= mono_metadata_token_index (token
);
5643 MonoGenericContext context
;
5644 MonoClassField
*field
;
5646 *error
= ResolveTokenError_Other
;
5648 /* Validate token */
5649 if ((table
!= MONO_TABLE_FIELD
) && (table
!= MONO_TABLE_MEMBERREF
)) {
5650 *error
= ResolveTokenError_BadTable
;
5654 if (image
->dynamic
) {
5655 if (type_args
|| method_args
)
5656 mono_raise_exception (mono_get_exception_not_implemented (NULL
));
5657 /* FIXME: validate memberref token type */
5658 return mono_lookup_dynamic_token_class (image
, token
, FALSE
, NULL
, NULL
);
5661 if ((index
<= 0) || (index
> image
->tables
[table
].rows
)) {
5662 *error
= ResolveTokenError_OutOfRange
;
5665 if ((table
== MONO_TABLE_MEMBERREF
) && (mono_metadata_memberref_is_method (image
, token
))) {
5666 *error
= ResolveTokenError_BadTable
;
5670 init_generic_context_from_args (&context
, type_args
, method_args
);
5671 field
= mono_field_from_token (image
, token
, &klass
, &context
);
5673 if (mono_loader_get_last_error ())
5674 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5681 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage
*image
, guint32 token
, MonoArray
*type_args
, MonoArray
*method_args
, MonoResolveTokenError
*error
)
5683 int table
= mono_metadata_token_table (token
);
5685 *error
= ResolveTokenError_Other
;
5688 case MONO_TABLE_TYPEDEF
:
5689 case MONO_TABLE_TYPEREF
:
5690 case MONO_TABLE_TYPESPEC
: {
5691 MonoType
*t
= ves_icall_System_Reflection_Module_ResolveTypeToken (image
, token
, type_args
, method_args
, error
);
5693 return (MonoObject
*)mono_type_get_object (mono_domain_get (), t
);
5697 case MONO_TABLE_METHOD
:
5698 case MONO_TABLE_METHODSPEC
: {
5699 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5701 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5705 case MONO_TABLE_FIELD
: {
5706 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5708 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5712 case MONO_TABLE_MEMBERREF
:
5713 if (mono_metadata_memberref_is_method (image
, token
)) {
5714 MonoMethod
*m
= ves_icall_System_Reflection_Module_ResolveMethodToken (image
, token
, type_args
, method_args
, error
);
5716 return (MonoObject
*)mono_method_get_object (mono_domain_get (), m
, m
->klass
);
5721 MonoClassField
*f
= ves_icall_System_Reflection_Module_ResolveFieldToken (image
, token
, type_args
, method_args
, error
);
5723 return (MonoObject
*)mono_field_get_object (mono_domain_get (), f
->parent
, f
);
5730 *error
= ResolveTokenError_BadTable
;
5737 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage
*image
, guint32 token
, MonoResolveTokenError
*error
)
5739 int table
= mono_metadata_token_table (token
);
5740 int idx
= mono_metadata_token_index (token
);
5741 MonoTableInfo
*tables
= image
->tables
;
5746 *error
= ResolveTokenError_OutOfRange
;
5748 /* FIXME: Support other tables ? */
5749 if (table
!= MONO_TABLE_STANDALONESIG
)
5755 if ((idx
== 0) || (idx
> tables
[MONO_TABLE_STANDALONESIG
].rows
))
5758 sig
= mono_metadata_decode_row_col (&tables
[MONO_TABLE_STANDALONESIG
], idx
- 1, 0);
5760 ptr
= mono_metadata_blob_heap (image
, sig
);
5761 len
= mono_metadata_decode_blob_size (ptr
, &ptr
);
5763 res
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, len
);
5764 memcpy (mono_array_addr (res
, guint8
, 0), ptr
, len
);
5768 static MonoReflectionType
*
5769 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder
*tb
, MonoString
*smodifiers
)
5772 int isbyref
= 0, rank
;
5773 char *str
= mono_string_to_utf8 (smodifiers
);
5776 MONO_ARCH_SAVE_REGS
;
5778 klass
= mono_class_from_mono_type (tb
->type
.type
);
5780 /* logic taken from mono_reflection_parse_type(): keep in sync */
5784 if (isbyref
) { /* only one level allowed by the spec */
5791 return mono_type_get_object (mono_object_domain (tb
), &klass
->this_arg
);
5794 klass
= mono_ptr_class_get (&klass
->byval_arg
);
5795 mono_class_init (klass
);
5806 else if (*p
!= '*') { /* '*' means unknown lower bound */
5817 klass
= mono_array_class_get (klass
, rank
);
5818 mono_class_init (klass
);
5825 return mono_type_get_object (mono_object_domain (tb
), &klass
->byval_arg
);
5829 ves_icall_Type_IsArrayImpl (MonoReflectionType
*t
)
5834 MONO_ARCH_SAVE_REGS
;
5837 res
= !type
->byref
&& (type
->type
== MONO_TYPE_ARRAY
|| type
->type
== MONO_TYPE_SZARRAY
);
5842 static MonoReflectionType
*
5843 ves_icall_Type_make_array_type (MonoReflectionType
*type
, int rank
)
5845 MonoClass
*klass
, *aklass
;
5847 MONO_ARCH_SAVE_REGS
;
5849 klass
= mono_class_from_mono_type (type
->type
);
5850 aklass
= mono_array_class_get (klass
, rank
);
5852 return mono_type_get_object (mono_object_domain (type
), &aklass
->byval_arg
);
5855 static MonoReflectionType
*
5856 ves_icall_Type_make_byref_type (MonoReflectionType
*type
)
5860 MONO_ARCH_SAVE_REGS
;
5862 klass
= mono_class_from_mono_type (type
->type
);
5864 return mono_type_get_object (mono_object_domain (type
), &klass
->this_arg
);
5867 static MonoReflectionType
*
5868 ves_icall_Type_MakePointerType (MonoReflectionType
*type
)
5872 MONO_ARCH_SAVE_REGS
;
5874 pklass
= mono_ptr_class_get (type
->type
);
5876 return mono_type_get_object (mono_object_domain (type
), &pklass
->byval_arg
);
5880 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType
*type
, MonoObject
*target
,
5881 MonoReflectionMethod
*info
)
5883 MonoClass
*delegate_class
= mono_class_from_mono_type (type
->type
);
5884 MonoObject
*delegate
;
5886 MonoMethod
*method
= info
->method
;
5888 MONO_ARCH_SAVE_REGS
;
5890 mono_assert (delegate_class
->parent
== mono_defaults
.multicastdelegate_class
);
5892 /* FIME: We must check if target is visible to the caller under coreclr.
5893 * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
5896 delegate
= mono_object_new (mono_object_domain (type
), delegate_class
);
5898 if (mono_method_needs_static_rgctx_invoke (method
, FALSE
)) {
5899 method
= mono_marshal_get_static_rgctx_invoke (method
);
5900 func
= mono_compile_method (method
);
5901 } else if (method
->dynamic
) {
5902 /* Creating a trampoline would leak memory */
5903 func
= mono_compile_method (method
);
5905 func
= mono_create_ftnptr (mono_domain_get (),
5906 mono_runtime_create_jump_trampoline (mono_domain_get (), method
, TRUE
));
5909 mono_delegate_ctor_with_method (delegate
, target
, func
, method
);
5915 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate
*this)
5917 /* Reset the invoke impl to the default one */
5918 this->invoke_impl
= mono_runtime_create_delegate_trampoline (this->object
.vtable
->klass
);
5922 * Magic number to convert a time which is relative to
5923 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5925 #define EPOCH_ADJUST ((guint64)62135596800LL)
5928 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5930 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5932 #ifdef PLATFORM_WIN32
5933 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5935 convert_to_absolute_date(SYSTEMTIME
*date
)
5937 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5938 static int days_in_month
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5939 static int leap_days_in_month
[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5940 /* from the calendar FAQ */
5941 int a
= (14 - date
->wMonth
) / 12;
5942 int y
= date
->wYear
- a
;
5943 int m
= date
->wMonth
+ 12 * a
- 2;
5944 int d
= (1 + y
+ y
/4 - y
/100 + y
/400 + (31*m
)/12) % 7;
5946 /* d is now the day of the week for the first of the month (0 == Sunday) */
5948 int day_of_week
= date
->wDayOfWeek
;
5950 /* set day_in_month to the first day in the month which falls on day_of_week */
5951 int day_in_month
= 1 + (day_of_week
- d
);
5952 if (day_in_month
<= 0)
5955 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5956 date
->wDay
= day_in_month
+ (date
->wDay
- 1) * 7;
5957 if (date
->wDay
> (IS_LEAP(date
->wYear
) ? leap_days_in_month
[date
->wMonth
- 1] : days_in_month
[date
->wMonth
- 1]))
5962 #ifndef PLATFORM_WIN32
5964 * Return's the offset from GMT of a local time.
5966 * tm is a local time
5967 * t is the same local time as seconds.
5970 gmt_offset(struct tm
*tm
, time_t t
)
5972 #if defined (HAVE_TM_GMTOFF)
5973 return tm
->tm_gmtoff
;
5978 g
.tm_isdst
= tm
->tm_isdst
;
5980 return (int)difftime(t
, t2
);
5985 * This is heavily based on zdump.c from glibc 2.2.
5987 * * data[0]: start of daylight saving time (in DateTime ticks).
5988 * * data[1]: end of daylight saving time (in DateTime ticks).
5989 * * data[2]: utcoffset (in TimeSpan ticks).
5990 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5991 * * name[0]: name of this timezone when not daylight saving.
5992 * * name[1]: name of this timezone when daylight saving.
5994 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5995 * the class library allows years between 1 and 9999.
5997 * Returns true on success and zero on failure.
6000 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year
, MonoArray
**data
, MonoArray
**names
)
6002 #ifndef PLATFORM_WIN32
6003 MonoDomain
*domain
= mono_domain_get ();
6004 struct tm start
, tt
;
6008 int is_daylight
= 0, day
;
6011 MONO_ARCH_SAVE_REGS
;
6013 MONO_CHECK_ARG_NULL (data
);
6014 MONO_CHECK_ARG_NULL (names
);
6016 (*data
) = mono_array_new (domain
, mono_defaults
.int64_class
, 4);
6017 (*names
) = mono_array_new (domain
, mono_defaults
.string_class
, 2);
6020 * no info is better than crashing: we'll need our own tz data
6021 * to make this work properly, anyway. The range is probably
6022 * reduced to 1970 .. 2037 because that is what mktime is
6023 * guaranteed to support (we get into an infinite loop
6027 memset (&start
, 0, sizeof (start
));
6030 start
.tm_year
= year
-1900;
6032 t
= mktime (&start
);
6034 if ((year
< 1970) || (year
> 2037) || (t
== -1)) {
6036 tt
= *localtime (&t
);
6037 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6038 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6039 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6043 gmtoff
= gmt_offset (&start
, t
);
6045 /* For each day of the year, calculate the tm_gmtoff. */
6046 for (day
= 0; day
< 365; day
++) {
6049 tt
= *localtime (&t
);
6051 /* Daylight saving starts or ends here. */
6052 if (gmt_offset (&tt
, t
) != gmtoff
) {
6056 /* Try to find the exact hour when daylight saving starts/ends. */
6060 tt1
= *localtime (&t1
);
6061 } while (gmt_offset (&tt1
, t1
) != gmtoff
);
6063 /* Try to find the exact minute when daylight saving starts/ends. */
6066 tt1
= *localtime (&t1
);
6067 } while (gmt_offset (&tt1
, t1
) == gmtoff
);
6069 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6071 /* Write data, if we're already in daylight saving, we're done. */
6073 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6074 mono_array_set ((*data
), gint64
, 1, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
6077 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6078 mono_array_set ((*data
), gint64
, 0, ((gint64
)t1
+ EPOCH_ADJUST
) * 10000000L);
6082 /* This is only set once when we enter daylight saving. */
6083 mono_array_set ((*data
), gint64
, 2, (gint64
)gmtoff
* 10000000L);
6084 mono_array_set ((*data
), gint64
, 3, (gint64
)(gmt_offset (&tt
, t
) - gmtoff
) * 10000000L);
6086 gmtoff
= gmt_offset (&tt
, t
);
6091 strftime (tzone
, sizeof (tzone
), "%Z", &tt
);
6092 mono_array_setref ((*names
), 0, mono_string_new (domain
, tzone
));
6093 mono_array_setref ((*names
), 1, mono_string_new (domain
, tzone
));
6094 mono_array_set ((*data
), gint64
, 0, 0);
6095 mono_array_set ((*data
), gint64
, 1, 0);
6096 mono_array_set ((*data
), gint64
, 2, (gint64
) gmtoff
* 10000000L);
6097 mono_array_set ((*data
), gint64
, 3, 0);
6102 MonoDomain
*domain
= mono_domain_get ();
6103 TIME_ZONE_INFORMATION tz_info
;
6108 tz_id
= GetTimeZoneInformation (&tz_info
);
6109 if (tz_id
== TIME_ZONE_ID_INVALID
)
6112 MONO_CHECK_ARG_NULL (data
);
6113 MONO_CHECK_ARG_NULL (names
);
6115 (*data
) = mono_array_new (domain
, mono_defaults
.int64_class
, 4);
6116 (*names
) = mono_array_new (domain
, mono_defaults
.string_class
, 2);
6118 for (i
= 0; i
< 32; ++i
)
6119 if (!tz_info
.DaylightName
[i
])
6121 mono_array_setref ((*names
), 1, mono_string_new_utf16 (domain
, tz_info
.DaylightName
, i
));
6122 for (i
= 0; i
< 32; ++i
)
6123 if (!tz_info
.StandardName
[i
])
6125 mono_array_setref ((*names
), 0, mono_string_new_utf16 (domain
, tz_info
.StandardName
, i
));
6127 if ((year
<= 1601) || (year
> 30827)) {
6129 * According to MSDN, the MS time functions can't handle dates outside
6135 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
6136 if (tz_id
!= TIME_ZONE_ID_UNKNOWN
) {
6137 tz_info
.StandardDate
.wYear
= year
;
6138 convert_to_absolute_date(&tz_info
.StandardDate
);
6139 err
= SystemTimeToFileTime (&tz_info
.StandardDate
, &ft
);
6144 mono_array_set ((*data
), gint64
, 1, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
6145 tz_info
.DaylightDate
.wYear
= year
;
6146 convert_to_absolute_date(&tz_info
.DaylightDate
);
6147 err
= SystemTimeToFileTime (&tz_info
.DaylightDate
, &ft
);
6152 mono_array_set ((*data
), gint64
, 0, FILETIME_ADJUST
+ (((guint64
)ft
.dwHighDateTime
<<32) | ft
.dwLowDateTime
));
6154 mono_array_set ((*data
), gint64
, 2, (tz_info
.Bias
+ tz_info
.StandardBias
) * -600000000LL);
6155 mono_array_set ((*data
), gint64
, 3, (tz_info
.DaylightBias
- tz_info
.StandardBias
) * -600000000LL);
6162 ves_icall_System_Object_obj_address (MonoObject
*this)
6164 MONO_ARCH_SAVE_REGS
;
6171 static inline gint32
6172 mono_array_get_byte_length (MonoArray
*array
)
6178 klass
= array
->obj
.vtable
->klass
;
6180 if (array
->bounds
== NULL
)
6181 length
= array
->max_length
;
6184 for (i
= 0; i
< klass
->rank
; ++ i
)
6185 length
*= array
->bounds
[i
].length
;
6188 switch (klass
->element_class
->byval_arg
.type
) {
6191 case MONO_TYPE_BOOLEAN
:
6195 case MONO_TYPE_CHAR
:
6203 return length
* sizeof (gpointer
);
6214 ves_icall_System_Buffer_ByteLengthInternal (MonoArray
*array
)
6216 MONO_ARCH_SAVE_REGS
;
6218 return mono_array_get_byte_length (array
);
6222 ves_icall_System_Buffer_GetByteInternal (MonoArray
*array
, gint32 idx
)
6224 MONO_ARCH_SAVE_REGS
;
6226 return mono_array_get (array
, gint8
, idx
);
6230 ves_icall_System_Buffer_SetByteInternal (MonoArray
*array
, gint32 idx
, gint8 value
)
6232 MONO_ARCH_SAVE_REGS
;
6234 mono_array_set (array
, gint8
, idx
, value
);
6238 ves_icall_System_Buffer_BlockCopyInternal (MonoArray
*src
, gint32 src_offset
, MonoArray
*dest
, gint32 dest_offset
, gint32 count
)
6240 guint8
*src_buf
, *dest_buf
;
6242 MONO_ARCH_SAVE_REGS
;
6244 /* watch out for integer overflow */
6245 if ((src_offset
> mono_array_get_byte_length (src
) - count
) || (dest_offset
> mono_array_get_byte_length (dest
) - count
))
6248 src_buf
= (guint8
*)src
->vector
+ src_offset
;
6249 dest_buf
= (guint8
*)dest
->vector
+ dest_offset
;
6252 memcpy (dest_buf
, src_buf
, count
);
6254 memmove (dest_buf
, src_buf
, count
); /* Source and dest are the same array */
6260 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject
*this, MonoString
*class_name
)
6262 MonoDomain
*domain
= mono_object_domain (this);
6264 MonoRealProxy
*rp
= ((MonoRealProxy
*)this);
6265 MonoTransparentProxy
*tp
;
6269 MONO_ARCH_SAVE_REGS
;
6271 res
= mono_object_new (domain
, mono_defaults
.transparent_proxy_class
);
6272 tp
= (MonoTransparentProxy
*) res
;
6274 MONO_OBJECT_SETREF (tp
, rp
, rp
);
6275 type
= ((MonoReflectionType
*)rp
->class_to_proxy
)->type
;
6276 klass
= mono_class_from_mono_type (type
);
6278 tp
->custom_type_info
= (mono_object_isinst (this, mono_defaults
.iremotingtypeinfo_class
) != NULL
);
6279 tp
->remote_class
= mono_remote_class (domain
, class_name
, klass
);
6281 res
->vtable
= mono_remote_class_vtable (domain
, tp
->remote_class
, rp
);
6285 static MonoReflectionType
*
6286 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy
*tp
)
6288 return mono_type_get_object (mono_object_domain (tp
), &tp
->remote_class
->proxy_class
->byval_arg
);
6291 /* System.Environment */
6294 ves_icall_System_Environment_get_MachineName (void)
6296 #if defined (PLATFORM_WIN32)
6301 len
= MAX_COMPUTERNAME_LENGTH
+ 1;
6302 buf
= g_new (gunichar2
, len
);
6305 if (GetComputerName (buf
, (PDWORD
) &len
))
6306 result
= mono_string_new_utf16 (mono_domain_get (), buf
, len
);
6314 if (gethostname (buf
, sizeof (buf
)) == 0)
6315 result
= mono_string_new (mono_domain_get (), buf
);
6324 ves_icall_System_Environment_get_Platform (void)
6326 #if defined (PLATFORM_WIN32)
6329 #elif defined(__MACH__)
6331 if (mono_framework_version () < 2)
6336 if (mono_framework_version () < 2)
6343 ves_icall_System_Environment_get_NewLine (void)
6345 MONO_ARCH_SAVE_REGS
;
6347 #if defined (PLATFORM_WIN32)
6348 return mono_string_new (mono_domain_get (), "\r\n");
6350 return mono_string_new (mono_domain_get (), "\n");
6355 ves_icall_System_Environment_GetEnvironmentVariable (MonoString
*name
)
6360 MONO_ARCH_SAVE_REGS
;
6365 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6366 value
= g_getenv (utf8_name
);
6373 return mono_string_new (mono_domain_get (), value
);
6377 * There is no standard way to get at environ.
6380 #ifndef __MINGW32_VERSION
6382 /* Apple defines this in crt_externs.h but doesn't provide that header for
6383 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6384 * in fact exist on all implementations (so far)
6386 gchar
***_NSGetEnviron();
6387 #define environ (*_NSGetEnviron())
6396 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6398 #ifdef PLATFORM_WIN32
6407 env_strings
= GetEnvironmentStrings();
6410 env_string
= env_strings
;
6411 while (*env_string
!= '\0') {
6412 /* weird case that MS seems to skip */
6413 if (*env_string
!= '=')
6415 while (*env_string
!= '\0')
6421 domain
= mono_domain_get ();
6422 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6426 env_string
= env_strings
;
6427 while (*env_string
!= '\0') {
6428 /* weird case that MS seems to skip */
6429 if (*env_string
!= '=') {
6430 equal_str
= wcschr(env_string
, '=');
6431 g_assert(equal_str
);
6432 str
= mono_string_new_utf16 (domain
, env_string
, equal_str
-env_string
);
6433 mono_array_setref (names
, n
, str
);
6436 while (*env_string
!= '\0')
6441 FreeEnvironmentStrings (env_strings
);
6453 MONO_ARCH_SAVE_REGS
;
6456 for (e
= environ
; *e
!= 0; ++ e
)
6459 domain
= mono_domain_get ();
6460 names
= mono_array_new (domain
, mono_defaults
.string_class
, n
);
6463 for (e
= environ
; *e
!= 0; ++ e
) {
6464 parts
= g_strsplit (*e
, "=", 2);
6466 str
= mono_string_new (domain
, *parts
);
6467 mono_array_setref (names
, n
, str
);
6480 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6482 #if !GLIB_CHECK_VERSION(2,4,0)
6483 #define g_setenv(a,b,c) setenv(a,b,c)
6484 #define g_unsetenv(a) unsetenv(a)
6488 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString
*name
, MonoString
*value
)
6490 #ifdef PLATFORM_WIN32
6491 gunichar2
*utf16_name
, *utf16_value
;
6493 gchar
*utf8_name
, *utf8_value
;
6496 MONO_ARCH_SAVE_REGS
;
6498 #ifdef PLATFORM_WIN32
6499 utf16_name
= mono_string_to_utf16 (name
);
6500 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6501 SetEnvironmentVariable (utf16_name
, NULL
);
6502 g_free (utf16_name
);
6506 utf16_value
= mono_string_to_utf16 (value
);
6508 SetEnvironmentVariable (utf16_name
, utf16_value
);
6510 g_free (utf16_name
);
6511 g_free (utf16_value
);
6513 utf8_name
= mono_string_to_utf8 (name
); /* FIXME: this should be ascii */
6515 if ((value
== NULL
) || (mono_string_length (value
) == 0) || (mono_string_chars (value
)[0] == 0)) {
6516 g_unsetenv (utf8_name
);
6521 utf8_value
= mono_string_to_utf8 (value
);
6522 g_setenv (utf8_name
, utf8_value
, TRUE
);
6525 g_free (utf8_value
);
6530 ves_icall_System_Environment_Exit (int result
)
6532 MONO_ARCH_SAVE_REGS
;
6534 mono_threads_set_shutting_down ();
6536 mono_runtime_set_shutting_down ();
6538 /* Suspend all managed threads since the runtime is going away */
6539 mono_thread_suspend_all_other_threads ();
6541 mono_runtime_quit ();
6543 /* we may need to do some cleanup here... */
6548 ves_icall_System_Environment_GetGacPath (void)
6550 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6554 ves_icall_System_Environment_GetWindowsFolderPath (int folder
)
6556 #if defined (PLATFORM_WIN32)
6557 #ifndef CSIDL_FLAG_CREATE
6558 #define CSIDL_FLAG_CREATE 0x8000
6561 WCHAR path
[MAX_PATH
];
6562 /* Create directory if no existing */
6563 if (SUCCEEDED (SHGetFolderPathW (NULL
, folder
| CSIDL_FLAG_CREATE
, NULL
, 0, path
))) {
6567 return mono_string_new_utf16 (mono_domain_get (), path
, len
);
6570 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6572 return mono_string_new (mono_domain_get (), "");
6576 ves_icall_System_Environment_GetLogicalDrives (void)
6578 gunichar2 buf
[128], *ptr
, *dname
;
6580 guint initial_size
= 127, size
= 128;
6583 MonoString
*drivestr
;
6584 MonoDomain
*domain
= mono_domain_get ();
6587 MONO_ARCH_SAVE_REGS
;
6592 while (size
> initial_size
) {
6593 size
= (guint
) GetLogicalDriveStrings (initial_size
, ptr
);
6594 if (size
> initial_size
) {
6597 ptr
= g_malloc0 ((size
+ 1) * sizeof (gunichar2
));
6598 initial_size
= size
;
6612 result
= mono_array_new (domain
, mono_defaults
.string_class
, ndrives
);
6617 while (*u16
) { u16
++; len
++; }
6618 drivestr
= mono_string_new_utf16 (domain
, dname
, len
);
6619 mono_array_setref (result
, ndrives
++, drivestr
);
6630 ves_icall_System_Environment_InternalGetHome (void)
6632 MONO_ARCH_SAVE_REGS
;
6634 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6637 static const char *encodings
[] = {
6639 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6640 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6641 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6643 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6644 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6645 "x_unicode_2_0_utf_7",
6647 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6648 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6650 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6653 "unicodefffe", "utf_16be",
6660 * Returns the internal codepage, if the value of "int_code_page" is
6661 * 1 at entry, and we can not compute a suitable code page number,
6662 * returns the code page as a string
6665 ves_icall_System_Text_Encoding_InternalCodePage (gint32
*int_code_page
)
6670 char *codepage
= NULL
;
6672 int want_name
= *int_code_page
;
6675 *int_code_page
= -1;
6676 MONO_ARCH_SAVE_REGS
;
6678 g_get_charset (&cset
);
6679 c
= codepage
= strdup (cset
);
6680 for (c
= codepage
; *c
; c
++){
6681 if (isascii (*c
) && isalpha (*c
))
6686 /* g_print ("charset: %s\n", cset); */
6688 /* handle some common aliases */
6691 for (i
= 0; p
!= 0; ){
6692 if ((gssize
) p
< 7){
6694 p
= encodings
[++i
];
6697 if (strcmp (p
, codepage
) == 0){
6698 *int_code_page
= code
;
6701 p
= encodings
[++i
];
6704 if (strstr (codepage
, "utf_8") != NULL
)
6705 *int_code_page
|= 0x10000000;
6708 if (want_name
&& *int_code_page
== -1)
6709 return mono_string_new (mono_domain_get (), cset
);
6715 ves_icall_System_Environment_get_HasShutdownStarted (void)
6717 if (mono_runtime_is_shutting_down ())
6720 if (mono_domain_is_unloading (mono_domain_get ()))
6727 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage
*this,
6728 MonoReflectionMethod
*method
,
6729 MonoArray
*out_args
)
6731 MONO_ARCH_SAVE_REGS
;
6733 mono_message_init (mono_object_domain (this), this, method
, out_args
);
6737 ves_icall_IsTransparentProxy (MonoObject
*proxy
)
6739 MONO_ARCH_SAVE_REGS
;
6744 if (proxy
->vtable
->klass
== mono_defaults
.transparent_proxy_class
)
6750 static MonoReflectionMethod
*
6751 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6752 MonoReflectionType
*rtype
, MonoReflectionMethod
*rmethod
)
6756 MonoMethod
**vtable
;
6757 MonoMethod
*res
= NULL
;
6759 MONO_CHECK_ARG_NULL (rtype
);
6760 MONO_CHECK_ARG_NULL (rmethod
);
6762 method
= rmethod
->method
;
6763 klass
= mono_class_from_mono_type (rtype
->type
);
6765 if (MONO_CLASS_IS_INTERFACE (klass
))
6768 if (method
->flags
& METHOD_ATTRIBUTE_STATIC
)
6771 if ((method
->flags
& METHOD_ATTRIBUTE_FINAL
) || !(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
)) {
6772 if (klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
))
6778 mono_class_setup_vtable (klass
);
6779 vtable
= klass
->vtable
;
6781 if (method
->klass
->flags
& TYPE_ATTRIBUTE_INTERFACE
) {
6782 int offs
= mono_class_interface_offset (klass
, method
->klass
);
6784 res
= vtable
[offs
+ method
->slot
];
6786 if (!(klass
== method
->klass
|| mono_class_is_subclass_of (klass
, method
->klass
, FALSE
)))
6789 if (method
->slot
!= -1)
6790 res
= vtable
[method
->slot
];
6796 return mono_method_get_object (mono_domain_get (), res
, NULL
);
6800 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType
*type
, MonoBoolean enable
)
6805 MONO_ARCH_SAVE_REGS
;
6807 klass
= mono_class_from_mono_type (type
->type
);
6808 vtable
= mono_class_vtable (mono_domain_get (), klass
);
6810 if (enable
) vtable
->remote
= 1;
6811 else vtable
->remote
= 0;
6815 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType
*type
)
6820 MONO_ARCH_SAVE_REGS
;
6822 domain
= mono_object_domain (type
);
6823 klass
= mono_class_from_mono_type (type
->type
);
6825 if (klass
->rank
>= 1) {
6826 g_assert (klass
->rank
== 1);
6827 return (MonoObject
*) mono_array_new (domain
, klass
->element_class
, 0);
6829 /* Bypass remoting object creation check */
6830 return mono_object_new_alloc_specific (mono_class_vtable (domain
, klass
));
6835 ves_icall_System_IO_get_temp_path (void)
6837 MONO_ARCH_SAVE_REGS
;
6839 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6843 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod
*method
)
6845 MONO_ARCH_SAVE_REGS
;
6847 return mono_compile_method (method
);
6851 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6856 MONO_ARCH_SAVE_REGS
;
6858 path
= g_build_path (G_DIR_SEPARATOR_S
, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version
, "machine.config", NULL
);
6860 #if defined (PLATFORM_WIN32)
6861 /* Avoid mixing '/' and '\\' */
6864 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6865 if (path
[i
] == '/')
6869 mcpath
= mono_string_new (mono_domain_get (), path
);
6876 get_bundled_machine_config (void)
6878 const gchar
*machine_config
;
6880 MONO_ARCH_SAVE_REGS
;
6882 machine_config
= mono_get_machine_config ();
6884 if (!machine_config
)
6887 return mono_string_new (mono_domain_get (), machine_config
);
6891 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6896 MONO_ARCH_SAVE_REGS
;
6898 path
= g_path_get_dirname (mono_get_config_dir ());
6900 #if defined (PLATFORM_WIN32)
6901 /* Avoid mixing '/' and '\\' */
6904 for (i
= strlen (path
) - 1; i
>= 0; i
--)
6905 if (path
[i
] == '/')
6909 ipath
= mono_string_new (mono_domain_get (), path
);
6916 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
6918 return mono_debug_using_mono_debugger ();
6922 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString
*message
)
6924 #if defined (PLATFORM_WIN32)
6925 OutputDebugString (mono_string_chars (message
));
6927 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6931 /* Only used for value types */
6933 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType
*type
)
6938 MONO_ARCH_SAVE_REGS
;
6940 domain
= mono_object_domain (type
);
6941 klass
= mono_class_from_mono_type (type
->type
);
6943 if (mono_class_is_nullable (klass
))
6944 /* No arguments -> null */
6947 return mono_object_new (domain
, klass
);
6950 static MonoReflectionMethod
*
6951 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod
*m
)
6953 MonoClass
*klass
, *parent
;
6954 MonoMethod
*method
= m
->method
;
6955 MonoMethod
*result
= NULL
;
6957 MONO_ARCH_SAVE_REGS
;
6959 if (method
->klass
== NULL
)
6962 if (!(method
->flags
& METHOD_ATTRIBUTE_VIRTUAL
) ||
6963 MONO_CLASS_IS_INTERFACE (method
->klass
) ||
6964 method
->flags
& METHOD_ATTRIBUTE_NEW_SLOT
)
6967 klass
= method
->klass
;
6968 if (klass
->generic_class
)
6969 klass
= klass
->generic_class
->container_class
;
6971 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6972 for (parent
= klass
->parent
; parent
!= NULL
; parent
= parent
->parent
) {
6973 mono_class_setup_vtable (parent
);
6974 if (parent
->vtable_size
<= method
->slot
)
6979 if (klass
== method
->klass
)
6982 result
= klass
->vtable
[method
->slot
];
6983 if (result
== NULL
) {
6984 /* It is an abstract method */
6985 gpointer iter
= NULL
;
6986 while ((result
= mono_class_get_methods (klass
, &iter
)))
6987 if (result
->slot
== method
->slot
)
6994 return mono_method_get_object (mono_domain_get (), result
, NULL
);
6998 ves_icall_MonoMethod_get_name (MonoReflectionMethod
*m
)
7000 MonoMethod
*method
= m
->method
;
7002 MONO_OBJECT_SETREF (m
, name
, mono_string_new (mono_object_domain (m
), method
->name
));
7007 mono_ArgIterator_Setup (MonoArgIterator
*iter
, char* argsp
, char* start
)
7009 MONO_ARCH_SAVE_REGS
;
7011 iter
->sig
= *(MonoMethodSignature
**)argsp
;
7013 g_assert (iter
->sig
->sentinelpos
<= iter
->sig
->param_count
);
7014 g_assert (iter
->sig
->call_convention
== MONO_CALL_VARARG
);
7017 /* FIXME: it's not documented what start is exactly... */
7021 guint32 i
, arg_size
;
7023 iter
->args
= argsp
+ sizeof (gpointer
);
7024 #ifndef MONO_ARCH_REGPARMS
7025 for (i
= 0; i
< iter
->sig
->sentinelpos
; ++i
) {
7026 arg_size
= mono_type_stack_size (iter
->sig
->params
[i
], &align
);
7027 iter
->args
= (char*)iter
->args
+ arg_size
;
7031 iter
->num_args
= iter
->sig
->param_count
- iter
->sig
->sentinelpos
;
7033 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7037 mono_ArgIterator_IntGetNextArg (MonoArgIterator
*iter
)
7039 guint32 i
, arg_size
;
7042 MONO_ARCH_SAVE_REGS
;
7044 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7046 g_assert (i
< iter
->sig
->param_count
);
7048 res
.type
= iter
->sig
->params
[i
];
7049 res
.klass
= mono_class_from_mono_type (res
.type
);
7050 res
.value
= iter
->args
;
7051 arg_size
= mono_type_stack_size (res
.type
, &align
);
7052 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7053 if (arg_size
<= sizeof (gpointer
)) {
7055 int padding
= arg_size
- mono_type_size (res
.type
, &dummy
);
7056 res
.value
= (guint8
*)res
.value
+ padding
;
7059 iter
->args
= (char*)iter
->args
+ arg_size
;
7062 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7068 mono_ArgIterator_IntGetNextArgT (MonoArgIterator
*iter
, MonoType
*type
)
7070 guint32 i
, arg_size
;
7073 MONO_ARCH_SAVE_REGS
;
7075 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7077 g_assert (i
< iter
->sig
->param_count
);
7079 while (i
< iter
->sig
->param_count
) {
7080 if (!mono_metadata_type_equal (type
, iter
->sig
->params
[i
]))
7082 res
.type
= iter
->sig
->params
[i
];
7083 res
.klass
= mono_class_from_mono_type (res
.type
);
7084 /* FIXME: endianess issue... */
7085 res
.value
= iter
->args
;
7086 arg_size
= mono_type_stack_size (res
.type
, &align
);
7087 iter
->args
= (char*)iter
->args
+ arg_size
;
7089 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7092 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7101 mono_ArgIterator_IntGetNextArgType (MonoArgIterator
*iter
)
7104 MONO_ARCH_SAVE_REGS
;
7106 i
= iter
->sig
->sentinelpos
+ iter
->next_arg
;
7108 g_assert (i
< iter
->sig
->param_count
);
7110 return iter
->sig
->params
[i
];
7114 mono_TypedReference_ToObject (MonoTypedRef tref
)
7116 MONO_ARCH_SAVE_REGS
;
7118 if (MONO_TYPE_IS_REFERENCE (tref
.type
)) {
7119 MonoObject
** objp
= tref
.value
;
7123 return mono_value_box (mono_domain_get (), tref
.klass
, tref
.value
);
7127 mono_TypedReference_ToObjectInternal (MonoType
*type
, gpointer value
, MonoClass
*klass
)
7129 MONO_ARCH_SAVE_REGS
;
7131 if (MONO_TYPE_IS_REFERENCE (type
)) {
7132 MonoObject
** objp
= value
;
7136 return mono_value_box (mono_domain_get (), klass
, value
);
7140 prelink_method (MonoMethod
*method
)
7142 const char *exc_class
, *exc_arg
;
7143 if (!(method
->flags
& METHOD_ATTRIBUTE_PINVOKE_IMPL
))
7145 mono_lookup_pinvoke_call (method
, &exc_class
, &exc_arg
);
7147 mono_raise_exception(
7148 mono_exception_from_name_msg (mono_defaults
.corlib
, "System", exc_class
, exc_arg
) );
7150 /* create the wrapper, too? */
7154 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod
*method
)
7156 MONO_ARCH_SAVE_REGS
;
7157 prelink_method (method
->method
);
7161 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType
*type
)
7163 MonoClass
*klass
= mono_class_from_mono_type (type
->type
);
7165 gpointer iter
= NULL
;
7166 MONO_ARCH_SAVE_REGS
;
7168 while ((m
= mono_class_get_methods (klass
, &iter
)))
7172 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7174 ves_icall_System_NumberFormatter_GetFormatterTables (guint64
const **mantissas
,
7175 gint32
const **exponents
,
7176 gunichar2
const **digitLowerTable
,
7177 gunichar2
const **digitUpperTable
,
7178 gint64
const **tenPowersList
,
7179 gint32
const **decHexDigits
)
7181 *mantissas
= Formatter_MantissaBitsTable
;
7182 *exponents
= Formatter_TensExponentTable
;
7183 *digitLowerTable
= Formatter_DigitLowerTable
;
7184 *digitUpperTable
= Formatter_DigitUpperTable
;
7185 *tenPowersList
= Formatter_TenPowersList
;
7186 *decHexDigits
= Formatter_DecHexDigits
;
7189 /* These parameters are "readonly" in corlib/System/Char.cs */
7191 ves_icall_System_Char_GetDataTablePointers (guint8
const **category_data
,
7192 guint8
const **numeric_data
,
7193 gdouble
const **numeric_data_values
,
7194 guint16
const **to_lower_data_low
,
7195 guint16
const **to_lower_data_high
,
7196 guint16
const **to_upper_data_low
,
7197 guint16
const **to_upper_data_high
)
7199 *category_data
= CategoryData
;
7200 *numeric_data
= NumericData
;
7201 *numeric_data_values
= NumericDataValues
;
7202 *to_lower_data_low
= ToLowerDataLow
;
7203 *to_lower_data_high
= ToLowerDataHigh
;
7204 *to_upper_data_low
= ToUpperDataLow
;
7205 *to_upper_data_high
= ToUpperDataHigh
;
7209 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod
*method
)
7211 return method
->method
->token
;
7215 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7216 * and avoid useless allocations.
7219 type_array_from_modifiers (MonoImage
*image
, MonoType
*type
, int optional
)
7223 for (i
= 0; i
< type
->num_mods
; ++i
) {
7224 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
))
7229 res
= mono_array_new (mono_domain_get (), mono_defaults
.systemtype_class
, count
);
7231 for (i
= 0; i
< type
->num_mods
; ++i
) {
7232 if ((optional
&& !type
->modifiers
[i
].required
) || (!optional
&& type
->modifiers
[i
].required
)) {
7233 MonoClass
*klass
= mono_class_get (image
, type
->modifiers
[i
].token
);
7234 mono_array_setref (res
, count
, mono_type_get_object (mono_domain_get (), &klass
->byval_arg
));
7242 param_info_get_type_modifiers (MonoReflectionParameter
*param
, MonoBoolean optional
)
7244 MonoType
*type
= param
->ClassImpl
->type
;
7245 MonoReflectionMethod
*method
= (MonoReflectionMethod
*)param
->MemberImpl
;
7246 MonoImage
*image
= method
->method
->klass
->image
;
7247 int pos
= param
->PositionImpl
;
7248 MonoMethodSignature
*sig
= mono_method_signature (method
->method
);
7252 type
= sig
->params
[pos
];
7254 return type_array_from_modifiers (image
, type
, optional
);
7258 get_property_type (MonoProperty
*prop
)
7260 MonoMethodSignature
*sig
;
7262 sig
= mono_method_signature (prop
->get
);
7264 } else if (prop
->set
) {
7265 sig
= mono_method_signature (prop
->set
);
7266 return sig
->params
[sig
->param_count
- 1];
7272 property_info_get_type_modifiers (MonoReflectionProperty
*property
, MonoBoolean optional
)
7274 MonoType
*type
= get_property_type (property
->property
);
7275 MonoImage
*image
= property
->klass
->image
;
7279 return type_array_from_modifiers (image
, type
, optional
);
7283 custom_attrs_defined_internal (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7285 MonoCustomAttrInfo
*cinfo
;
7288 cinfo
= mono_reflection_get_custom_attrs_info (obj
);
7291 found
= mono_custom_attrs_has_attr (cinfo
, mono_class_from_mono_type (attr_type
->type
));
7293 mono_custom_attrs_free (cinfo
);
7298 custom_attrs_get_by_type (MonoObject
*obj
, MonoReflectionType
*attr_type
)
7300 MonoArray
*res
= mono_reflection_get_custom_attrs_by_type (obj
, attr_type
? mono_class_from_mono_type (attr_type
->type
) : NULL
);
7302 if (mono_loader_get_last_error ()) {
7303 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7304 g_assert_not_reached ();
7311 GCHandle_CheckCurrentDomain (guint32 gchandle
)
7313 return mono_gchandle_is_in_domain (gchandle
, mono_domain_get ());
7317 ves_icall_Mono_Runtime_GetDisplayName (void)
7319 static const char display_name_str
[] = "Mono " VERSION
;
7320 MonoString
*display_name
= mono_string_new (mono_domain_get (), display_name_str
);
7321 return display_name
;
7325 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code
)
7327 MonoString
*message
;
7331 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
7332 FORMAT_MESSAGE_IGNORE_INSERTS
, NULL
, code
, 0,
7335 message
= mono_string_new (mono_domain_get (), "Error looking up error string");
7337 message
= mono_string_new_utf16 (mono_domain_get (), buf
, ret
);
7345 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7346 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7347 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7348 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7349 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7350 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7351 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7352 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7356 base64_to_byte_array (gunichar2
*start
, gint ilength
, MonoBoolean allowWhitespaceOnly
)
7361 gunichar2 last
, prev_last
, prev2_last
;
7369 last
= prev_last
= 0, prev2_last
= 0;
7370 for (i
= 0; i
< ilength
; i
++) {
7372 if (c
>= sizeof (dbase64
)) {
7373 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7374 "System", "FormatException",
7375 "Invalid character found.");
7376 mono_raise_exception (exc
);
7377 } else if (isspace (c
)) {
7380 prev2_last
= prev_last
;
7386 olength
= ilength
- ignored
;
7388 if (allowWhitespaceOnly
&& olength
== 0) {
7389 return mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, 0);
7392 if ((olength
& 3) != 0 || olength
<= 0) {
7393 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System",
7394 "FormatException", "Invalid length.");
7395 mono_raise_exception (exc
);
7398 if (prev2_last
== '=') {
7399 exc
= mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7400 mono_raise_exception (exc
);
7403 olength
= (olength
* 3) / 4;
7407 if (prev_last
== '=')
7410 result
= mono_array_new (mono_domain_get (), mono_defaults
.byte_class
, olength
);
7411 res_ptr
= mono_array_addr (result
, guchar
, 0);
7412 for (i
= 0; i
< ilength
; ) {
7415 for (k
= 0; k
< 4 && i
< ilength
;) {
7421 if (((b
[k
] = dbase64
[c
]) & 0x80) != 0) {
7422 exc
= mono_exception_from_name_msg (mono_get_corlib (),
7423 "System", "FormatException",
7424 "Invalid character found.");
7425 mono_raise_exception (exc
);
7430 *res_ptr
++ = (b
[0] << 2) | (b
[1] >> 4);
7432 *res_ptr
++ = (b
[1] << 4) | (b
[2] >> 2);
7434 *res_ptr
++ = (b
[2] << 6) | b
[3];
7436 while (i
< ilength
&& isspace (start
[i
]))
7444 InternalFromBase64String (MonoString
*str
, MonoBoolean allowWhitespaceOnly
)
7446 MONO_ARCH_SAVE_REGS
;
7448 return base64_to_byte_array (mono_string_chars (str
),
7449 mono_string_length (str
), allowWhitespaceOnly
);
7453 InternalFromBase64CharArray (MonoArray
*input
, gint offset
, gint length
)
7455 MONO_ARCH_SAVE_REGS
;
7457 return base64_to_byte_array (mono_array_addr (input
, gunichar2
, offset
),
7461 #define ICALL_TYPE(id,name,first)
7462 #define ICALL(id,name,func) Icall_ ## id,
7465 #include "metadata/icall-def.h"
7471 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7472 #define ICALL(id,name,func)
7474 #include "metadata/icall-def.h"
7480 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7481 #define ICALL(id,name,func)
7483 guint16 first_icall
;
7486 static const IcallTypeDesc
7487 icall_type_descs
[] = {
7488 #include "metadata/icall-def.h"
7492 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7495 #define ICALL_TYPE(id,name,first)
7498 #ifdef HAVE_ARRAY_ELEM_INIT
7499 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7500 #define MSGSTRFIELD1(line) str##line
7502 static const struct msgstrtn_t
{
7503 #define ICALL(id,name,func)
7505 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7506 #include "metadata/icall-def.h"
7508 } icall_type_names_str
= {
7509 #define ICALL_TYPE(id,name,first) (name),
7510 #include "metadata/icall-def.h"
7513 static const guint16 icall_type_names_idx
[] = {
7514 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7515 #include "metadata/icall-def.h"
7518 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7520 static const struct msgstr_t
{
7522 #define ICALL_TYPE(id,name,first)
7523 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7524 #include "metadata/icall-def.h"
7526 } icall_names_str
= {
7527 #define ICALL(id,name,func) (name),
7528 #include "metadata/icall-def.h"
7531 static const guint16 icall_names_idx
[] = {
7532 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7533 #include "metadata/icall-def.h"
7536 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7542 #define ICALL_TYPE(id,name,first) name,
7543 #define ICALL(id,name,func)
7544 static const char* const
7545 icall_type_names
[] = {
7546 #include "metadata/icall-def.h"
7550 #define icall_type_name_get(id) (icall_type_names [(id)])
7554 #define ICALL_TYPE(id,name,first)
7555 #define ICALL(id,name,func) name,
7556 static const char* const
7558 #include "metadata/icall-def.h"
7561 #define icall_name_get(id) icall_names [(id)]
7563 #endif /* !HAVE_ARRAY_ELEM_INIT */
7567 #define ICALL_TYPE(id,name,first)
7568 #define ICALL(id,name,func) func,
7569 static const gconstpointer
7570 icall_functions
[] = {
7571 #include "metadata/icall-def.h"
7575 static GHashTable
*icall_hash
= NULL
;
7576 static GHashTable
*jit_icall_hash_name
= NULL
;
7577 static GHashTable
*jit_icall_hash_addr
= NULL
;
7580 mono_icall_init (void)
7584 /* check that tables are sorted: disable in release */
7587 const char *prev_class
= NULL
;
7588 const char *prev_method
;
7590 for (i
= 0; i
< Icall_type_num
; ++i
) {
7591 const IcallTypeDesc
*desc
;
7594 if (prev_class
&& strcmp (prev_class
, icall_type_name_get (i
)) >= 0)
7595 g_print ("class %s should come before class %s\n", icall_type_name_get (i
), prev_class
);
7596 prev_class
= icall_type_name_get (i
);
7597 desc
= &icall_type_descs
[i
];
7598 num_icalls
= icall_desc_num_icalls (desc
);
7599 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7600 for (j
= 0; j
< num_icalls
; ++j
) {
7601 const char *methodn
= icall_name_get (desc
->first_icall
+ j
);
7602 if (prev_method
&& strcmp (prev_method
, methodn
) >= 0)
7603 g_print ("method %s should come before method %s\n", methodn
, prev_method
);
7604 prev_method
= methodn
;
7609 icall_hash
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
7613 mono_icall_cleanup (void)
7615 g_hash_table_destroy (icall_hash
);
7616 g_hash_table_destroy (jit_icall_hash_name
);
7617 g_hash_table_destroy (jit_icall_hash_addr
);
7621 mono_add_internal_call (const char *name
, gconstpointer method
)
7623 mono_loader_lock ();
7625 g_hash_table_insert (icall_hash
, g_strdup (name
), (gpointer
) method
);
7627 mono_loader_unlock ();
7630 #ifdef HAVE_ARRAY_ELEM_INIT
7632 compare_method_imap (const void *key
, const void *elem
)
7634 const char* method_name
= (const char*)&icall_names_str
+ (*(guint16
*)elem
);
7635 return strcmp (key
, method_name
);
7639 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7641 const guint16
*nameslot
= bsearch (name
, icall_names_idx
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names_idx
[0]), compare_method_imap
);
7644 return (gpointer
)icall_functions
[(nameslot
- &icall_names_idx
[0])];
7648 compare_class_imap (const void *key
, const void *elem
)
7650 const char* class_name
= (const char*)&icall_type_names_str
+ (*(guint16
*)elem
);
7651 return strcmp (key
, class_name
);
7654 static const IcallTypeDesc
*
7655 find_class_icalls (const char *name
)
7657 const guint16
*nameslot
= bsearch (name
, icall_type_names_idx
, Icall_type_num
, sizeof (icall_type_names_idx
[0]), compare_class_imap
);
7660 return &icall_type_descs
[nameslot
- &icall_type_names_idx
[0]];
7665 compare_method_imap (const void *key
, const void *elem
)
7667 const char** method_name
= (const char**)elem
;
7668 return strcmp (key
, *method_name
);
7672 find_method_icall (const IcallTypeDesc
*imap
, const char *name
)
7674 const char **nameslot
= bsearch (name
, icall_names
+ imap
->first_icall
, icall_desc_num_icalls (imap
), sizeof (icall_names
[0]), compare_method_imap
);
7677 return (gpointer
)icall_functions
[(nameslot
- icall_names
)];
7681 compare_class_imap (const void *key
, const void *elem
)
7683 const char** class_name
= (const char**)elem
;
7684 return strcmp (key
, *class_name
);
7687 static const IcallTypeDesc
*
7688 find_class_icalls (const char *name
)
7690 const char **nameslot
= bsearch (name
, icall_type_names
, Icall_type_num
, sizeof (icall_type_names
[0]), compare_class_imap
);
7693 return &icall_type_descs
[nameslot
- icall_type_names
];
7699 * we should probably export this as an helper (handle nested types).
7700 * Returns the number of chars written in buf.
7703 concat_class_name (char *buf
, int bufsize
, MonoClass
*klass
)
7705 int nspacelen
, cnamelen
;
7706 nspacelen
= strlen (klass
->name_space
);
7707 cnamelen
= strlen (klass
->name
);
7708 if (nspacelen
+ cnamelen
+ 2 > bufsize
)
7711 memcpy (buf
, klass
->name_space
, nspacelen
);
7712 buf
[nspacelen
++] = '.';
7714 memcpy (buf
+ nspacelen
, klass
->name
, cnamelen
);
7715 buf
[nspacelen
+ cnamelen
] = 0;
7716 return nspacelen
+ cnamelen
;
7720 mono_lookup_internal_call (MonoMethod
*method
)
7725 int typelen
= 0, mlen
, siglen
;
7727 const IcallTypeDesc
*imap
;
7729 g_assert (method
!= NULL
);
7731 if (method
->is_inflated
)
7732 method
= ((MonoMethodInflated
*) method
)->declaring
;
7734 if (method
->klass
->nested_in
) {
7735 int pos
= concat_class_name (mname
, sizeof (mname
)-2, method
->klass
->nested_in
);
7739 mname
[pos
++] = '/';
7742 typelen
= concat_class_name (mname
+pos
, sizeof (mname
)-pos
-1, method
->klass
);
7748 typelen
= concat_class_name (mname
, sizeof (mname
), method
->klass
);
7753 imap
= find_class_icalls (mname
);
7755 mname
[typelen
] = ':';
7756 mname
[typelen
+ 1] = ':';
7758 mlen
= strlen (method
->name
);
7759 memcpy (mname
+ typelen
+ 2, method
->name
, mlen
);
7760 sigstart
= mname
+ typelen
+ 2 + mlen
;
7763 tmpsig
= mono_signature_get_desc (mono_method_signature (method
), TRUE
);
7764 siglen
= strlen (tmpsig
);
7765 if (typelen
+ mlen
+ siglen
+ 6 > sizeof (mname
))
7768 memcpy (sigstart
+ 1, tmpsig
, siglen
);
7769 sigstart
[siglen
+ 1] = ')';
7770 sigstart
[siglen
+ 2] = 0;
7773 mono_loader_lock ();
7775 res
= g_hash_table_lookup (icall_hash
, mname
);
7777 mono_loader_unlock ();
7780 /* try without signature */
7782 res
= g_hash_table_lookup (icall_hash
, mname
);
7784 mono_loader_unlock ();
7788 /* it wasn't found in the static call tables */
7790 mono_loader_unlock ();
7793 res
= find_method_icall (imap
, sigstart
- mlen
);
7795 mono_loader_unlock ();
7798 /* try _with_ signature */
7800 res
= find_method_icall (imap
, sigstart
- mlen
);
7802 mono_loader_unlock ();
7806 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname
);
7807 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7808 g_print ("The out of sync library is: %s\n", method
->klass
->image
->name
);
7809 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7810 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");
7811 g_print ("If you see other errors or faults after this message they are probably related\n");
7812 g_print ("and you need to fix your mono install first.\n");
7814 mono_loader_unlock ();
7820 type_from_typename (char *typename
)
7822 MonoClass
*klass
= NULL
; /* assignment to shut GCC warning up */
7824 if (!strcmp (typename
, "int"))
7825 klass
= mono_defaults
.int_class
;
7826 else if (!strcmp (typename
, "ptr"))
7827 klass
= mono_defaults
.int_class
;
7828 else if (!strcmp (typename
, "void"))
7829 klass
= mono_defaults
.void_class
;
7830 else if (!strcmp (typename
, "int32"))
7831 klass
= mono_defaults
.int32_class
;
7832 else if (!strcmp (typename
, "uint32"))
7833 klass
= mono_defaults
.uint32_class
;
7834 else if (!strcmp (typename
, "int8"))
7835 klass
= mono_defaults
.sbyte_class
;
7836 else if (!strcmp (typename
, "uint8"))
7837 klass
= mono_defaults
.byte_class
;
7838 else if (!strcmp (typename
, "int16"))
7839 klass
= mono_defaults
.int16_class
;
7840 else if (!strcmp (typename
, "uint16"))
7841 klass
= mono_defaults
.uint16_class
;
7842 else if (!strcmp (typename
, "long"))
7843 klass
= mono_defaults
.int64_class
;
7844 else if (!strcmp (typename
, "ulong"))
7845 klass
= mono_defaults
.uint64_class
;
7846 else if (!strcmp (typename
, "float"))
7847 klass
= mono_defaults
.single_class
;
7848 else if (!strcmp (typename
, "double"))
7849 klass
= mono_defaults
.double_class
;
7850 else if (!strcmp (typename
, "object"))
7851 klass
= mono_defaults
.object_class
;
7852 else if (!strcmp (typename
, "obj"))
7853 klass
= mono_defaults
.object_class
;
7854 else if (!strcmp (typename
, "string"))
7855 klass
= mono_defaults
.string_class
;
7856 else if (!strcmp (typename
, "bool"))
7857 klass
= mono_defaults
.boolean_class
;
7858 else if (!strcmp (typename
, "boolean"))
7859 klass
= mono_defaults
.boolean_class
;
7862 g_assert_not_reached ();
7864 return &klass
->byval_arg
;
7867 MonoMethodSignature
*
7868 mono_create_icall_signature (const char *sigstr
)
7873 MonoMethodSignature
*res
;
7875 mono_loader_lock ();
7876 res
= g_hash_table_lookup (mono_defaults
.corlib
->helper_signatures
, sigstr
);
7878 mono_loader_unlock ();
7882 parts
= g_strsplit (sigstr
, " ", 256);
7891 res
= mono_metadata_signature_alloc (mono_defaults
.corlib
, len
- 1);
7894 #ifdef PLATFORM_WIN32
7896 * Under windows, the default pinvoke calling convention is STDCALL but
7899 res
->call_convention
= MONO_CALL_C
;
7902 res
->ret
= type_from_typename (parts
[0]);
7903 for (i
= 1; i
< len
; ++i
) {
7904 res
->params
[i
- 1] = type_from_typename (parts
[i
]);
7909 g_hash_table_insert (mono_defaults
.corlib
->helper_signatures
, (gpointer
)sigstr
, res
);
7911 mono_loader_unlock ();
7917 mono_find_jit_icall_by_name (const char *name
)
7919 MonoJitICallInfo
*info
;
7920 g_assert (jit_icall_hash_name
);
7922 mono_loader_lock ();
7923 info
= g_hash_table_lookup (jit_icall_hash_name
, name
);
7924 mono_loader_unlock ();
7929 mono_find_jit_icall_by_addr (gconstpointer addr
)
7931 MonoJitICallInfo
*info
;
7932 g_assert (jit_icall_hash_addr
);
7934 mono_loader_lock ();
7935 info
= g_hash_table_lookup (jit_icall_hash_addr
, (gpointer
)addr
);
7936 mono_loader_unlock ();
7942 * mono_get_jit_icall_info:
7944 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7945 * caller should access it while holding the loader lock.
7948 mono_get_jit_icall_info (void)
7950 return jit_icall_hash_name
;
7954 mono_register_jit_icall_wrapper (MonoJitICallInfo
*info
, gconstpointer wrapper
)
7956 mono_loader_lock ();
7957 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)wrapper
, info
);
7958 mono_loader_unlock ();
7962 mono_register_jit_icall (gconstpointer func
, const char *name
, MonoMethodSignature
*sig
, gboolean is_save
)
7964 MonoJitICallInfo
*info
;
7969 mono_loader_lock ();
7971 if (!jit_icall_hash_name
) {
7972 jit_icall_hash_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, g_free
);
7973 jit_icall_hash_addr
= g_hash_table_new (NULL
, NULL
);
7976 if (g_hash_table_lookup (jit_icall_hash_name
, name
)) {
7977 g_warning ("jit icall already defined \"%s\"\n", name
);
7978 g_assert_not_reached ();
7981 info
= g_new0 (MonoJitICallInfo
, 1);
7988 info
->wrapper
= func
;
7990 info
->wrapper
= NULL
;
7993 g_hash_table_insert (jit_icall_hash_name
, (gpointer
)info
->name
, info
);
7994 g_hash_table_insert (jit_icall_hash_addr
, (gpointer
)func
, info
);
7996 mono_loader_unlock ();