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/metadata/object.h>
28 #include <mono/metadata/threads.h>
29 #include <mono/metadata/threads-types.h>
30 #include <mono/metadata/threadpool.h>
31 #include <mono/metadata/monitor.h>
32 #include <mono/metadata/reflection.h>
33 #include <mono/metadata/assembly.h>
34 #include <mono/metadata/tabledefs.h>
35 #include <mono/metadata/exception.h>
36 #include <mono/metadata/file-io.h>
37 #include <mono/metadata/console-io.h>
38 #include <mono/metadata/socket-io.h>
39 #include <mono/metadata/mono-endian.h>
40 #include <mono/metadata/tokentype.h>
41 #include <mono/metadata/domain-internals.h>
42 #include <mono/metadata/metadata-internals.h>
43 #include <mono/metadata/class-internals.h>
44 #include <mono/metadata/marshal.h>
45 #include <mono/metadata/gc-internal.h>
46 #include <mono/metadata/mono-gc.h>
47 #include <mono/metadata/rand.h>
48 #include <mono/metadata/sysmath.h>
49 #include <mono/metadata/string-icalls.h>
50 #include <mono/metadata/debug-helpers.h>
51 #include <mono/metadata/process.h>
52 #include <mono/metadata/environment.h>
53 #include <mono/metadata/profiler-private.h>
54 #include <mono/metadata/locales.h>
55 #include <mono/metadata/filewatcher.h>
56 #include <mono/metadata/char-conversions.h>
57 #include <mono/metadata/security.h>
58 #include <mono/metadata/mono-config.h>
59 #include <mono/metadata/cil-coff.h>
60 #include <mono/metadata/security-manager.h>
61 #include <mono/metadata/security-core-clr.h>
62 #include <mono/io-layer/io-layer.h>
63 #include <mono/utils/strtod.h>
64 #include <mono/utils/monobitset.h>
66 #if defined (PLATFORM_WIN32)
72 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
75 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
77 static inline MonoBoolean
78 is_generic_parameter (MonoType *type)
80 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
84 * We expect a pointer to a char, not a string
87 mono_double_ParseImpl (char *ptr, double *result)
96 *result = strtod (ptr, &endptr);
99 *result = mono_strtod (ptr, &endptr);
102 if (!*ptr || (endptr && *endptr))
109 mono_class_get_throw (MonoImage *image, guint32 type_token)
111 MonoClass *class = mono_class_get (image, type_token);
112 MonoLoaderError *error;
118 error = mono_loader_get_last_error ();
119 g_assert (error != NULL);
121 ex = mono_loader_error_prepare_exception (error);
122 mono_raise_exception (ex);
127 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
136 ao = (MonoArray *)this;
137 ac = (MonoClass *)ao->obj.vtable->klass;
139 esize = mono_array_element_size (ac);
140 ea = (gpointer*)((char*)ao->vector + (pos * esize));
142 if (ac->element_class->valuetype)
143 return mono_value_box (this->vtable->domain, ac->element_class, ea);
149 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
157 MONO_CHECK_ARG_NULL (idxs);
159 io = (MonoArray *)idxs;
160 ic = (MonoClass *)io->obj.vtable->klass;
162 ao = (MonoArray *)this;
163 ac = (MonoClass *)ao->obj.vtable->klass;
165 g_assert (ic->rank == 1);
166 if (io->bounds != NULL || io->max_length != ac->rank)
167 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
169 ind = (gint32 *)io->vector;
171 if (ao->bounds == NULL) {
172 if (*ind < 0 || *ind >= ao->max_length)
173 mono_raise_exception (mono_get_exception_index_out_of_range ());
175 return ves_icall_System_Array_GetValueImpl (this, *ind);
178 for (i = 0; i < ac->rank; i++)
179 if ((ind [i] < ao->bounds [i].lower_bound) ||
180 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
181 mono_raise_exception (mono_get_exception_index_out_of_range ());
183 pos = ind [0] - ao->bounds [0].lower_bound;
184 for (i = 1; i < ac->rank; i++)
185 pos = pos*ao->bounds [i].length + ind [i] -
186 ao->bounds [i].lower_bound;
188 return ves_icall_System_Array_GetValueImpl (this, pos);
192 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
194 MonoClass *ac, *vc, *ec;
206 vc = value->vtable->klass;
210 ac = this->obj.vtable->klass;
211 ec = ac->element_class;
213 esize = mono_array_element_size (ac);
214 ea = (gpointer*)((char*)this->vector + (pos * esize));
215 va = (gpointer*)((char*)value + sizeof (MonoObject));
218 memset (ea, 0, esize);
222 #define NO_WIDENING_CONVERSION G_STMT_START{\
223 mono_raise_exception (mono_get_exception_argument ( \
224 "value", "not a widening conversion")); \
227 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
228 if (esize < vsize + (extra)) \
229 mono_raise_exception (mono_get_exception_argument ( \
230 "value", "not a widening conversion")); \
233 #define INVALID_CAST G_STMT_START{\
234 mono_raise_exception (mono_get_exception_invalid_cast ()); \
237 /* Check element (destination) type. */
238 switch (ec->byval_arg.type) {
239 case MONO_TYPE_STRING:
240 switch (vc->byval_arg.type) {
241 case MONO_TYPE_STRING:
247 case MONO_TYPE_BOOLEAN:
248 switch (vc->byval_arg.type) {
249 case MONO_TYPE_BOOLEAN:
262 NO_WIDENING_CONVERSION;
269 if (!ec->valuetype) {
270 if (!mono_object_isinst (value, ec))
272 *ea = (gpointer)value;
276 if (mono_object_isinst (value, ec)) {
277 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
284 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
286 et = ec->byval_arg.type;
287 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
288 et = ec->byval_arg.data.klass->enum_basetype->type;
290 vt = vc->byval_arg.type;
291 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
292 vt = vc->byval_arg.data.klass->enum_basetype->type;
294 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
300 case MONO_TYPE_CHAR: \
301 CHECK_WIDENING_CONVERSION(0); \
302 *(etype *) ea = (etype) u64; \
304 /* You can't assign a signed value to an unsigned array. */ \
309 /* You can't assign a floating point number to an integer array. */ \
312 NO_WIDENING_CONVERSION; \
316 #define ASSIGN_SIGNED(etype) G_STMT_START{\
322 CHECK_WIDENING_CONVERSION(0); \
323 *(etype *) ea = (etype) i64; \
325 /* You can assign an unsigned value to a signed array if the array's */ \
326 /* element size is larger than the value size. */ \
331 case MONO_TYPE_CHAR: \
332 CHECK_WIDENING_CONVERSION(1); \
333 *(etype *) ea = (etype) u64; \
335 /* You can't assign a floating point number to an integer array. */ \
338 NO_WIDENING_CONVERSION; \
342 #define ASSIGN_REAL(etype) G_STMT_START{\
346 CHECK_WIDENING_CONVERSION(0); \
347 *(etype *) ea = (etype) r64; \
349 /* All integer values fit into a floating point array, so we don't */ \
350 /* need to CHECK_WIDENING_CONVERSION here. */ \
355 *(etype *) ea = (etype) i64; \
361 case MONO_TYPE_CHAR: \
362 *(etype *) ea = (etype) u64; \
369 u64 = *(guint8 *) va;
372 u64 = *(guint16 *) va;
375 u64 = *(guint32 *) va;
378 u64 = *(guint64 *) va;
384 i64 = *(gint16 *) va;
387 i64 = *(gint32 *) va;
390 i64 = *(gint64 *) va;
393 r64 = *(gfloat *) va;
396 r64 = *(gdouble *) va;
399 u64 = *(guint16 *) va;
401 case MONO_TYPE_BOOLEAN:
402 /* Boolean is only compatible with itself. */
415 NO_WIDENING_CONVERSION;
422 /* If we can't do a direct copy, let's try a widening conversion. */
425 ASSIGN_UNSIGNED (guint16);
427 ASSIGN_UNSIGNED (guint8);
429 ASSIGN_UNSIGNED (guint16);
431 ASSIGN_UNSIGNED (guint32);
433 ASSIGN_UNSIGNED (guint64);
435 ASSIGN_SIGNED (gint8);
437 ASSIGN_SIGNED (gint16);
439 ASSIGN_SIGNED (gint32);
441 ASSIGN_SIGNED (gint64);
443 ASSIGN_REAL (gfloat);
445 ASSIGN_REAL (gdouble);
449 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
453 #undef NO_WIDENING_CONVERSION
454 #undef CHECK_WIDENING_CONVERSION
455 #undef ASSIGN_UNSIGNED
461 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
469 MONO_CHECK_ARG_NULL (idxs);
471 ic = idxs->obj.vtable->klass;
472 ac = this->obj.vtable->klass;
474 g_assert (ic->rank == 1);
475 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
476 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
478 ind = (gint32 *)idxs->vector;
480 if (this->bounds == NULL) {
481 if (*ind < 0 || *ind >= this->max_length)
482 mono_raise_exception (mono_get_exception_index_out_of_range ());
484 ves_icall_System_Array_SetValueImpl (this, value, *ind);
488 for (i = 0; i < ac->rank; i++)
489 if ((ind [i] < this->bounds [i].lower_bound) ||
490 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
491 mono_raise_exception (mono_get_exception_index_out_of_range ());
493 pos = ind [0] - this->bounds [0].lower_bound;
494 for (i = 1; i < ac->rank; i++)
495 pos = pos * this->bounds [i].length + ind [i] -
496 this->bounds [i].lower_bound;
498 ves_icall_System_Array_SetValueImpl (this, value, pos);
502 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
507 gboolean bounded = FALSE;
511 MONO_CHECK_ARG_NULL (type);
512 MONO_CHECK_ARG_NULL (lengths);
514 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
516 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
518 for (i = 0; i < mono_array_length (lengths); i++)
519 if (mono_array_get (lengths, gint32, i) < 0)
520 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
522 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
523 /* vectors are not the same as one dimensional arrays with no-zero bounds */
528 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
530 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
531 for (i = 0; i < aklass->rank; ++i) {
532 sizes [i] = mono_array_get (lengths, guint32, i);
534 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
536 sizes [i + aklass->rank] = 0;
539 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
545 ves_icall_System_Array_GetRank (MonoObject *this)
549 return this->vtable->klass->rank;
553 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
555 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
559 if ((dimension < 0) || (dimension >= rank))
560 mono_raise_exception (mono_get_exception_index_out_of_range ());
562 if (this->bounds == NULL)
563 return this->max_length;
565 return this->bounds [dimension].length;
569 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
571 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
575 if ((dimension < 0) || (dimension >= rank))
576 mono_raise_exception (mono_get_exception_index_out_of_range ());
578 if (this->bounds == NULL)
581 return this->bounds [dimension].lower_bound;
585 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
587 int sz = mono_array_element_size (mono_object_class (arr));
588 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
592 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
597 MonoClass *src_class;
598 MonoClass *dest_class;
603 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
606 if (source->bounds || dest->bounds)
609 if ((dest_idx + length > mono_array_length (dest)) ||
610 (source_idx + length > mono_array_length (source)))
613 src_class = source->obj.vtable->klass->element_class;
614 dest_class = dest->obj.vtable->klass->element_class;
617 * Handle common cases.
620 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
621 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
622 int has_refs = dest_class->has_references;
623 for (i = source_idx; i < source_idx + length; ++i) {
624 MonoObject *elem = mono_array_get (source, MonoObject*, i);
625 if (elem && !mono_object_isinst (elem, dest_class))
629 element_size = mono_array_element_size (dest->obj.vtable->klass);
630 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
631 for (i = 0; i < length; ++i) {
632 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
633 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
637 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
639 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
644 /* Check if we're copying a char[] <==> (u)short[] */
645 if (src_class != dest_class) {
646 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
649 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
651 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
652 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
653 for (i = source_idx; i < source_idx + length; ++i) {
654 MonoObject *elem = mono_array_get (source, MonoObject*, i);
655 if (elem && !mono_object_isinst (elem, dest_class))
662 if (dest_class->valuetype) {
663 element_size = mono_array_element_size (source->obj.vtable->klass);
664 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
665 if (dest_class->has_references) {
666 mono_value_copy_array (dest, dest_idx, source_addr, length);
668 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
669 memmove (dest_addr, source_addr, element_size * length);
672 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
679 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
688 ao = (MonoArray *)this;
689 ac = (MonoClass *)ao->obj.vtable->klass;
691 esize = mono_array_element_size (ac);
692 ea = (gpointer*)((char*)ao->vector + (pos * esize));
694 memcpy (value, ea, esize);
698 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
707 ao = (MonoArray *)this;
708 ac = (MonoClass *)ao->obj.vtable->klass;
710 esize = mono_array_element_size (ac);
711 ea = (gpointer*)((char*)ao->vector + (pos * esize));
713 memcpy (ea, value, esize);
717 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
719 MonoClass *klass = array->obj.vtable->klass;
720 guint32 size = mono_array_element_size (klass);
721 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
724 if (MONO_TYPE_IS_REFERENCE (type) ||
725 (type->type == MONO_TYPE_VALUETYPE &&
726 (!mono_type_get_class (type) ||
727 mono_type_get_class (type)->has_references))) {
728 MonoException *exc = mono_get_exception_argument("array",
729 "Cannot initialize array containing references");
730 mono_raise_exception (exc);
733 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
734 MonoException *exc = mono_get_exception_argument("field_handle",
735 "Field doesn't have an RVA");
736 mono_raise_exception (exc);
739 size *= array->max_length;
741 if (size > mono_type_size (field_handle->type, &align)) {
742 MonoException *exc = mono_get_exception_argument("field_handle",
743 "Field not large enough to fill array");
744 mono_raise_exception (exc);
747 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
749 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
750 guint ## n *src = (guint ## n *) field_handle->data; \
751 guint ## n *end = (guint ## n *)((char*)src + size); \
753 for (; src < end; data++, src++) { \
754 *data = read ## n (src); \
758 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
760 switch (type->type) {
777 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
781 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
783 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
786 double *data = (double*)mono_array_addr (array, double, 0);
788 for (i = 0; i < size; i++, data++) {
798 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
802 return offsetof (MonoString, chars);
806 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
810 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
813 return mono_object_clone (obj);
817 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
823 MONO_CHECK_ARG_NULL (handle);
825 klass = mono_class_from_mono_type (handle);
826 MONO_CHECK_ARG (handle, klass);
828 /* This will call the type constructor */
829 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
833 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
837 mono_image_check_for_module_cctor (image);
838 if (image->has_module_cctor) {
839 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
840 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
845 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
849 return mono_object_clone (this);
853 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
856 MonoObject **values = NULL;
860 MonoClassField* field;
865 klass = mono_object_class (this);
867 if (mono_class_num_fields (klass) == 0)
868 return mono_object_hash (this);
871 * Compute the starting value of the hashcode for fields of primitive
872 * types, and return the remaining fields in an array to the managed side.
873 * This way, we can avoid costly reflection operations in managed code.
876 while ((field = mono_class_get_fields (klass, &iter))) {
877 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
879 if (mono_field_is_deleted (field))
881 /* FIXME: Add more types */
882 switch (field->type->type) {
884 result ^= *(gint32*)((guint8*)this + field->offset);
886 case MONO_TYPE_STRING: {
888 s = *(MonoString**)((guint8*)this + field->offset);
890 result ^= mono_string_hash (s);
895 values = g_newa (MonoObject*, mono_class_num_fields (klass));
896 o = mono_field_get_value_object (mono_object_domain (this), field, this);
897 values [count++] = o;
903 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
904 for (i = 0; i < count; ++i)
905 mono_array_setref (*fields, i, values [i]);
913 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
916 MonoObject **values = NULL;
918 MonoClassField* field;
924 MONO_CHECK_ARG_NULL (that);
926 if (this->vtable != that->vtable)
929 klass = mono_object_class (this);
932 * Do the comparison for fields of primitive type and return a result if
933 * possible. Otherwise, return the remaining fields in an array to the
934 * managed side. This way, we can avoid costly reflection operations in
939 while ((field = mono_class_get_fields (klass, &iter))) {
940 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
942 if (mono_field_is_deleted (field))
944 /* FIXME: Add more types */
945 switch (field->type->type) {
947 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
950 case MONO_TYPE_STRING: {
952 guint32 s1len, s2len;
953 s1 = *(MonoString**)((guint8*)this + field->offset);
954 s2 = *(MonoString**)((guint8*)that + field->offset);
957 if ((s1 == NULL) || (s2 == NULL))
959 s1len = mono_string_length (s1);
960 s2len = mono_string_length (s2);
964 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
970 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
971 o = mono_field_get_value_object (mono_object_domain (this), field, this);
972 values [count++] = o;
973 o = mono_field_get_value_object (mono_object_domain (this), field, that);
974 values [count++] = o;
980 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
981 for (i = 0; i < count; ++i)
982 mono_array_setref (*fields, i, values [i]);
989 static MonoReflectionType *
990 ves_icall_System_Object_GetType (MonoObject *obj)
994 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
995 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
997 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1001 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1003 MONO_ARCH_SAVE_REGS;
1005 mtype->type = &obj->vtable->klass->byval_arg;
1006 g_assert (mtype->type->type);
1010 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1012 MONO_ARCH_SAVE_REGS;
1014 MONO_CHECK_ARG_NULL (obj);
1016 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
1020 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1021 MonoReflectionMethod *method,
1022 MonoArray *opt_param_types)
1024 MONO_ARCH_SAVE_REGS;
1026 MONO_CHECK_ARG_NULL (method);
1028 return mono_image_create_method_token (
1029 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1033 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1035 MONO_ARCH_SAVE_REGS;
1037 mono_image_create_pefile (mb, file);
1041 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1043 MONO_ARCH_SAVE_REGS;
1045 mono_image_build_metadata (mb);
1049 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1051 MonoMethod **dest = data;
1053 /* skip unmanaged frames */
1068 static MonoReflectionType *
1069 type_from_name (const char *str, MonoBoolean ignoreCase)
1071 MonoType *type = NULL;
1072 MonoAssembly *assembly = NULL;
1073 MonoTypeNameParse info;
1074 char *temp_str = g_strdup (str);
1075 gboolean type_resolve = FALSE;
1077 MONO_ARCH_SAVE_REGS;
1079 /* mono_reflection_parse_type() mangles the string */
1080 if (!mono_reflection_parse_type (temp_str, &info)) {
1081 mono_reflection_free_type_info (&info);
1086 if (info.assembly.name) {
1087 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1089 MonoMethod *m = mono_method_get_last_managed ();
1090 MonoMethod *dest = m;
1092 mono_stack_walk_no_il (get_caller, &dest);
1097 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1098 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1099 * to crash. This only seems to happen in some strange remoting
1100 * scenarios and I was unable to figure out what's happening there.
1101 * Dec 10, 2005 - Martin.
1105 assembly = dest->klass->image->assembly;
1107 g_warning (G_STRLOC);
1112 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1114 if (!info.assembly.name && !type) /* try mscorlib */
1115 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1117 mono_reflection_free_type_info (&info);
1123 return mono_type_get_object (mono_domain_get (), type);
1127 MonoReflectionType *
1128 mono_type_get (const char *str)
1130 char *copy = g_strdup (str);
1131 MonoReflectionType *type = type_from_name (copy, FALSE);
1138 static MonoReflectionType*
1139 ves_icall_type_from_name (MonoString *name,
1140 MonoBoolean throwOnError,
1141 MonoBoolean ignoreCase)
1143 char *str = mono_string_to_utf8 (name);
1144 MonoReflectionType *type;
1146 type = type_from_name (str, ignoreCase);
1149 MonoException *e = NULL;
1152 e = mono_get_exception_type_load (name, NULL);
1154 mono_loader_clear_error ();
1156 mono_raise_exception (e);
1163 static MonoReflectionType*
1164 ves_icall_type_from_handle (MonoType *handle)
1166 MonoDomain *domain = mono_domain_get ();
1167 MonoClass *klass = mono_class_from_mono_type (handle);
1169 MONO_ARCH_SAVE_REGS;
1171 mono_class_init (klass);
1172 return mono_type_get_object (domain, handle);
1176 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1178 MONO_ARCH_SAVE_REGS;
1180 if (c && type->type && c->type)
1181 return mono_metadata_type_equal (type->type, c->type);
1186 /* System.TypeCode */
1205 TYPECODE_STRING = 18
1209 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1211 int t = type->type->type;
1213 MONO_ARCH_SAVE_REGS;
1215 if (type->type->byref)
1216 return TYPECODE_OBJECT;
1220 case MONO_TYPE_VOID:
1221 return TYPECODE_OBJECT;
1222 case MONO_TYPE_BOOLEAN:
1223 return TYPECODE_BOOLEAN;
1225 return TYPECODE_BYTE;
1227 return TYPECODE_SBYTE;
1229 return TYPECODE_UINT16;
1231 return TYPECODE_INT16;
1232 case MONO_TYPE_CHAR:
1233 return TYPECODE_CHAR;
1237 return TYPECODE_OBJECT;
1239 return TYPECODE_UINT32;
1241 return TYPECODE_INT32;
1243 return TYPECODE_UINT64;
1245 return TYPECODE_INT64;
1247 return TYPECODE_SINGLE;
1249 return TYPECODE_DOUBLE;
1250 case MONO_TYPE_VALUETYPE:
1251 if (type->type->data.klass->enumtype) {
1252 t = type->type->data.klass->enum_basetype->type;
1255 MonoClass *k = type->type->data.klass;
1256 if (strcmp (k->name_space, "System") == 0) {
1257 if (strcmp (k->name, "Decimal") == 0)
1258 return TYPECODE_DECIMAL;
1259 else if (strcmp (k->name, "DateTime") == 0)
1260 return TYPECODE_DATETIME;
1263 return TYPECODE_OBJECT;
1264 case MONO_TYPE_STRING:
1265 return TYPECODE_STRING;
1266 case MONO_TYPE_SZARRAY:
1267 case MONO_TYPE_ARRAY:
1268 case MONO_TYPE_OBJECT:
1270 case MONO_TYPE_MVAR:
1271 case MONO_TYPE_TYPEDBYREF:
1272 return TYPECODE_OBJECT;
1273 case MONO_TYPE_CLASS:
1275 MonoClass *k = type->type->data.klass;
1276 if (strcmp (k->name_space, "System") == 0) {
1277 if (strcmp (k->name, "DBNull") == 0)
1278 return TYPECODE_DBNULL;
1281 return TYPECODE_OBJECT;
1282 case MONO_TYPE_GENERICINST:
1283 return TYPECODE_OBJECT;
1285 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1291 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1297 MONO_ARCH_SAVE_REGS;
1299 g_assert (type != NULL);
1301 domain = ((MonoObject *)type)->vtable->domain;
1303 if (!c) /* FIXME: dont know what do do here */
1306 klass = mono_class_from_mono_type (type->type);
1307 klassc = mono_class_from_mono_type (c->type);
1309 if (type->type->byref)
1310 return klassc == mono_defaults.object_class;
1312 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1316 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1322 MONO_ARCH_SAVE_REGS;
1324 g_assert (type != NULL);
1326 domain = ((MonoObject *)type)->vtable->domain;
1328 klass = mono_class_from_mono_type (type->type);
1329 klassc = mono_class_from_mono_type (c->type);
1331 if (type->type->byref && !c->type->byref)
1334 return mono_class_is_assignable_from (klass, klassc);
1338 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1340 MonoClass *klass = mono_class_from_mono_type (type->type);
1341 return mono_object_isinst (obj, klass) != NULL;
1345 ves_icall_get_attributes (MonoReflectionType *type)
1347 MonoClass *klass = mono_class_from_mono_type (type->type);
1349 MONO_ARCH_SAVE_REGS;
1351 return klass->flags;
1354 static MonoReflectionMarshal*
1355 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1357 MonoClass *klass = field->field->parent;
1358 MonoMarshalType *info;
1361 if (klass->generic_container ||
1362 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1365 info = mono_marshal_load_type_info (klass);
1367 for (i = 0; i < info->num_fields; ++i) {
1368 if (info->fields [i].field == field->field) {
1369 if (!info->fields [i].mspec)
1372 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1379 static MonoReflectionField*
1380 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1385 klass = handle->parent;
1387 /* FIXME: check that handle is a field of klass or of a parent: return null
1388 * and throw the exception in managed code.
1390 return mono_field_get_object (mono_domain_get (), klass, handle);
1393 static MonoReflectionField*
1394 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1396 MONO_ARCH_SAVE_REGS;
1400 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1404 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1406 MonoType *type = field->field->type;
1408 return type_array_from_modifiers (field->field->parent->image, type, optional);
1412 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1414 MonoDomain *domain = mono_domain_get ();
1415 MonoMethodSignature* sig;
1416 MONO_ARCH_SAVE_REGS;
1418 sig = mono_method_signature (method);
1420 g_assert (mono_loader_get_last_error ());
1421 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1424 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1425 info->ret = mono_type_get_object (domain, sig->ret);
1426 info->attrs = method->flags;
1427 info->implattrs = method->iflags;
1428 if (sig->call_convention == MONO_CALL_DEFAULT)
1431 if (sig->call_convention == MONO_CALL_VARARG)
1436 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1440 ves_icall_get_parameter_info (MonoMethod *method)
1442 MonoDomain *domain = mono_domain_get ();
1444 return mono_param_get_objects (domain, method);
1447 static MonoReflectionMarshal*
1448 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1450 MonoDomain *domain = mono_domain_get ();
1451 MonoReflectionMarshal* res = NULL;
1452 MonoMarshalSpec **mspecs;
1455 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1456 mono_method_get_marshal_info (method, mspecs);
1459 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1461 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1463 mono_metadata_free_marshal_spec (mspecs [i]);
1470 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1472 return field->field->offset - sizeof (MonoObject);
1475 static MonoReflectionType*
1476 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1479 MONO_ARCH_SAVE_REGS;
1481 parent = declaring? field->field->parent: field->klass;
1483 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1487 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1490 MonoClassField *cf = field->field;
1494 MonoDomain *domain = mono_object_domain (field);
1496 gboolean is_static = FALSE;
1497 gboolean is_ref = FALSE;
1499 MONO_ARCH_SAVE_REGS;
1501 if (field->klass->image->assembly->ref_only)
1502 mono_raise_exception (mono_get_exception_invalid_operation (
1503 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1505 mono_class_init (field->klass);
1507 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1510 if (obj && !is_static) {
1511 /* Check that the field belongs to the object */
1512 gboolean found = FALSE;
1515 for (k = obj->vtable->klass; k; k = k->parent) {
1516 if (k == cf->parent) {
1523 char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", cf->name, cf->parent->name, obj->vtable->klass->name);
1524 MonoException *ex = mono_get_exception_argument (NULL, msg);
1526 mono_raise_exception (ex);
1530 t = mono_type_get_underlying_type (cf->type);
1532 case MONO_TYPE_STRING:
1533 case MONO_TYPE_OBJECT:
1534 case MONO_TYPE_CLASS:
1535 case MONO_TYPE_ARRAY:
1536 case MONO_TYPE_SZARRAY:
1541 case MONO_TYPE_BOOLEAN:
1544 case MONO_TYPE_CHAR:
1553 case MONO_TYPE_VALUETYPE:
1556 case MONO_TYPE_GENERICINST:
1557 if (mono_type_generic_inst_is_valuetype (t)) {
1564 g_error ("type 0x%x not handled in "
1565 "ves_icall_Monofield_GetValue", t->type);
1571 vtable = mono_class_vtable (domain, cf->parent);
1572 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1573 mono_runtime_class_init (vtable);
1578 mono_field_static_get_value (vtable, cf, &o);
1580 mono_field_get_value (obj, cf, &o);
1585 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1586 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1589 /* Convert the Nullable structure into a boxed vtype */
1591 buf = (guint8*)vtable->data + cf->offset;
1593 buf = (guint8*)obj + cf->offset;
1595 return mono_nullable_box (buf, nklass);
1598 /* boxed value type */
1599 klass = mono_class_from_mono_type (cf->type);
1600 o = mono_object_new (domain, klass);
1601 v = ((gchar *) o) + sizeof (MonoObject);
1603 mono_field_static_get_value (vtable, cf, v);
1605 mono_field_get_value (obj, cf, v);
1612 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1614 MonoClassField *cf = field->field;
1617 MONO_ARCH_SAVE_REGS;
1619 if (field->klass->image->assembly->ref_only)
1620 mono_raise_exception (mono_get_exception_invalid_operation (
1621 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1623 v = (gchar *) value;
1624 if (!cf->type->byref) {
1625 switch (cf->type->type) {
1628 case MONO_TYPE_BOOLEAN:
1631 case MONO_TYPE_CHAR:
1640 case MONO_TYPE_VALUETYPE:
1642 v += sizeof (MonoObject);
1644 case MONO_TYPE_STRING:
1645 case MONO_TYPE_OBJECT:
1646 case MONO_TYPE_CLASS:
1647 case MONO_TYPE_ARRAY:
1648 case MONO_TYPE_SZARRAY:
1651 case MONO_TYPE_GENERICINST: {
1652 MonoGenericClass *gclass = cf->type->data.generic_class;
1653 g_assert (!gclass->context.class_inst->is_open);
1655 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1656 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1657 MonoObject *nullable;
1660 * Convert the boxed vtype into a Nullable structure.
1661 * This is complicated by the fact that Nullables have
1662 * a variable structure.
1664 nullable = mono_object_new (mono_domain_get (), nklass);
1666 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1668 v = mono_object_unbox (nullable);
1671 if (gclass->container_class->valuetype && (v != NULL))
1672 v += sizeof (MonoObject);
1676 g_error ("type 0x%x not handled in "
1677 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1682 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1683 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1684 if (!vtable->initialized)
1685 mono_runtime_class_init (vtable);
1686 mono_field_static_set_value (vtable, cf, v);
1688 mono_field_set_value (obj, cf, v);
1693 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1695 MonoObject *o = NULL;
1696 MonoClassField *field = this->field;
1698 MonoDomain *domain = mono_object_domain (this);
1700 MonoTypeEnum def_type;
1701 const char *def_value;
1703 MONO_ARCH_SAVE_REGS;
1705 mono_class_init (field->parent);
1707 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1708 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1710 if (field->parent->image->dynamic) {
1712 g_assert_not_reached ();
1715 def_value = mono_class_get_field_default_value (field, &def_type);
1720 case MONO_TYPE_BOOLEAN:
1723 case MONO_TYPE_CHAR:
1731 case MONO_TYPE_R8: {
1734 /* boxed value type */
1735 t = g_new0 (MonoType, 1);
1737 klass = mono_class_from_mono_type (t);
1739 o = mono_object_new (domain, klass);
1740 v = ((gchar *) o) + sizeof (MonoObject);
1741 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1744 case MONO_TYPE_STRING:
1745 case MONO_TYPE_CLASS:
1746 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1749 g_assert_not_reached ();
1755 static MonoReflectionType*
1756 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1758 MonoMethod *method = rmethod->method.method;
1760 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1763 /* From MonoProperty.cs */
1765 PInfo_Attributes = 1,
1766 PInfo_GetMethod = 1 << 1,
1767 PInfo_SetMethod = 1 << 2,
1768 PInfo_ReflectedType = 1 << 3,
1769 PInfo_DeclaringType = 1 << 4,
1774 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1776 MonoDomain *domain = mono_object_domain (property);
1778 MONO_ARCH_SAVE_REGS;
1780 if ((req_info & PInfo_ReflectedType) != 0)
1781 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1782 else if ((req_info & PInfo_DeclaringType) != 0)
1783 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1785 if ((req_info & PInfo_Name) != 0)
1786 info->name = mono_string_new (domain, property->property->name);
1788 if ((req_info & PInfo_Attributes) != 0)
1789 info->attrs = property->property->attrs;
1791 if ((req_info & PInfo_GetMethod) != 0)
1792 info->get = property->property->get ?
1793 mono_method_get_object (domain, property->property->get, property->klass): NULL;
1795 if ((req_info & PInfo_SetMethod) != 0)
1796 info->set = property->property->set ?
1797 mono_method_get_object (domain, property->property->set, property->klass): NULL;
1799 * There may be other methods defined for properties, though, it seems they are not exposed
1800 * in the reflection API
1805 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1807 MonoDomain *domain = mono_object_domain (event);
1809 MONO_ARCH_SAVE_REGS;
1811 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1812 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1814 info->name = mono_string_new (domain, event->event->name);
1815 info->attrs = event->event->attrs;
1816 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1817 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1818 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1820 if (event->event->other) {
1822 while (event->event->other [n])
1824 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1826 for (i = 0; i < n; i++)
1827 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1832 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1834 MonoDomain *domain = mono_object_domain (type);
1836 GPtrArray *ifaces = NULL;
1838 MonoClass *class = mono_class_from_mono_type (type->type);
1841 MonoGenericContext *context = NULL;
1843 MONO_ARCH_SAVE_REGS;
1845 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1846 context = mono_class_get_context (class);
1847 class = class->generic_class->container_class;
1850 mono_class_setup_vtable (class);
1852 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1854 for (parent = class; parent; parent = parent->parent) {
1855 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1857 for (i = 0; i < tmp_ifaces->len; ++i) {
1858 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1860 if (mono_bitset_test (slots, ic->interface_id))
1863 mono_bitset_set (slots, ic->interface_id);
1865 ifaces = g_ptr_array_new ();
1866 g_ptr_array_add (ifaces, ic);
1868 g_ptr_array_free (tmp_ifaces, TRUE);
1871 mono_bitset_free (slots);
1874 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1876 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1877 for (i = 0; i < ifaces->len; ++i) {
1878 MonoClass *ic = g_ptr_array_index (ifaces, i);
1879 MonoType *ret = &ic->byval_arg;
1880 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1881 ret = mono_class_inflate_generic_type (ret, context);
1883 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1885 g_ptr_array_free (ifaces, TRUE);
1891 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1893 MonoClass *class = mono_class_from_mono_type (type->type);
1894 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1895 MonoReflectionMethod *member;
1898 int i = 0, len, ioffset;
1901 MONO_ARCH_SAVE_REGS;
1903 mono_class_setup_vtable (class);
1905 /* type doesn't implement iface: the exception is thrown in managed code */
1906 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1909 len = mono_class_num_methods (iclass);
1910 ioffset = mono_class_interface_offset (class, iclass);
1911 domain = mono_object_domain (type);
1912 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1913 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1916 while ((method = mono_class_get_methods (iclass, &iter))) {
1917 member = mono_method_get_object (domain, method, iclass);
1918 mono_array_setref (*methods, i, member);
1919 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1920 mono_array_setref (*targets, i, member);
1927 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1929 MonoClass *klass = mono_class_from_mono_type (type->type);
1931 g_assert (!klass->image->dynamic);
1933 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1936 static MonoReflectionType*
1937 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1939 MonoClass *class = mono_class_from_mono_type (type->type);
1941 MONO_ARCH_SAVE_REGS;
1943 // GetElementType should only return a type for:
1944 // Array Pointer PassedByRef
1945 if (type->type->byref)
1946 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1947 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1948 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1949 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1950 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1955 static MonoReflectionType*
1956 ves_icall_get_type_parent (MonoReflectionType *type)
1958 MonoClass *class = mono_class_from_mono_type (type->type);
1960 MONO_ARCH_SAVE_REGS;
1962 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1966 ves_icall_type_ispointer (MonoReflectionType *type)
1968 MONO_ARCH_SAVE_REGS;
1970 return type->type->type == MONO_TYPE_PTR;
1974 ves_icall_type_isprimitive (MonoReflectionType *type)
1976 MONO_ARCH_SAVE_REGS;
1978 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)));
1982 ves_icall_type_isbyref (MonoReflectionType *type)
1984 MONO_ARCH_SAVE_REGS;
1986 return type->type->byref;
1990 ves_icall_type_iscomobject (MonoReflectionType *type)
1992 MonoClass *klass = mono_class_from_mono_type (type->type);
1993 MONO_ARCH_SAVE_REGS;
1995 return (klass && klass->is_com_object);
1998 static MonoReflectionModule*
1999 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2001 MonoClass *class = mono_class_from_mono_type (type->type);
2003 MONO_ARCH_SAVE_REGS;
2005 return mono_module_get_object (mono_object_domain (type), class->image);
2008 static MonoReflectionAssembly*
2009 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2011 MonoDomain *domain = mono_domain_get ();
2012 MonoClass *class = mono_class_from_mono_type (type->type);
2014 MONO_ARCH_SAVE_REGS;
2016 return mono_assembly_get_object (domain, class->image->assembly);
2019 static MonoReflectionType*
2020 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2022 MonoDomain *domain = mono_domain_get ();
2025 MONO_ARCH_SAVE_REGS;
2027 if (type->type->byref)
2029 if (type->type->type == MONO_TYPE_VAR)
2030 class = type->type->data.generic_param->owner->owner.klass;
2031 else if (type->type->type == MONO_TYPE_MVAR)
2032 class = type->type->data.generic_param->owner->owner.method->klass;
2034 class = mono_class_from_mono_type (type->type)->nested_in;
2036 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2039 static MonoReflectionType*
2040 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2042 MonoDomain *domain = mono_domain_get ();
2043 MonoClass *class = mono_class_from_mono_type (type->type);
2045 MONO_ARCH_SAVE_REGS;
2047 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2048 return mono_type_get_object (domain, class->enum_basetype);
2049 else if (class->element_class)
2050 return mono_type_get_object (domain, &class->element_class->byval_arg);
2056 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2058 MonoDomain *domain = mono_domain_get ();
2059 MonoClass *class = mono_class_from_mono_type (type->type);
2061 MONO_ARCH_SAVE_REGS;
2063 if (type->type->byref) {
2064 char *n = g_strdup_printf ("%s&", class->name);
2065 MonoString *res = mono_string_new (domain, n);
2071 return mono_string_new (domain, class->name);
2076 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2078 MonoDomain *domain = mono_domain_get ();
2079 MonoClass *class = mono_class_from_mono_type (type->type);
2081 MONO_ARCH_SAVE_REGS;
2083 while (class->nested_in)
2084 class = class->nested_in;
2086 if (class->name_space [0] == '\0')
2089 return mono_string_new (domain, class->name_space);
2093 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2095 MonoClass *class = mono_class_from_mono_type (type->type);
2097 MONO_ARCH_SAVE_REGS;
2103 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2106 MonoClass *klass, *pklass;
2108 MONO_ARCH_SAVE_REGS;
2110 klass = mono_class_from_mono_type (type->type);
2112 if (klass->generic_container) {
2113 MonoGenericContainer *container = klass->generic_container;
2114 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2115 for (i = 0; i < container->type_argc; ++i) {
2116 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2117 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2119 } else if (klass->generic_class) {
2120 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2121 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2122 for (i = 0; i < inst->type_argc; ++i)
2123 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2125 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2131 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2134 MONO_ARCH_SAVE_REGS;
2136 if (type->type->byref)
2139 klass = mono_class_from_mono_type (type->type);
2141 return klass->generic_container != NULL;
2144 static MonoReflectionType*
2145 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2148 MONO_ARCH_SAVE_REGS;
2150 if (type->type->byref)
2153 klass = mono_class_from_mono_type (type->type);
2154 if (klass->generic_container) {
2155 return type; /* check this one */
2157 if (klass->generic_class) {
2158 MonoClass *generic_class = klass->generic_class->container_class;
2160 if (generic_class->wastypebuilder && generic_class->reflection_info)
2161 return generic_class->reflection_info;
2163 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2168 static MonoReflectionType*
2169 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2171 MonoType *geninst, **types;
2174 MONO_ARCH_SAVE_REGS;
2176 count = mono_array_length (type_array);
2177 types = g_new0 (MonoType *, count);
2179 for (i = 0; i < count; i++) {
2180 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2181 types [i] = t->type;
2184 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2189 return mono_type_get_object (mono_object_domain (type), geninst);
2193 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2196 MONO_ARCH_SAVE_REGS;
2198 if (type->type->byref)
2201 klass = mono_class_from_mono_type (type->type);
2202 return klass->generic_class != NULL;
2206 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2209 MONO_ARCH_SAVE_REGS;
2211 if (type->type->byref)
2214 klass = mono_class_from_mono_type (type->type);
2215 return klass->generic_class != NULL || klass->generic_container != NULL;
2219 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2221 MONO_ARCH_SAVE_REGS;
2223 if (is_generic_parameter (type->type))
2224 return type->type->data.generic_param->num;
2228 static GenericParameterAttributes
2229 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2231 MONO_ARCH_SAVE_REGS;
2232 g_assert (is_generic_parameter (type->type));
2233 return type->type->data.generic_param->flags;
2237 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2239 MonoGenericParam *param;
2245 MONO_ARCH_SAVE_REGS;
2247 domain = mono_object_domain (type);
2248 param = type->type->data.generic_param;
2249 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2252 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2253 for (i = 0; i < count; i++)
2254 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2261 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2263 MONO_ARCH_SAVE_REGS;
2264 return is_generic_parameter (type->type);
2268 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2270 MONO_ARCH_SAVE_REGS;
2271 return is_generic_parameter (tb->type.type);
2275 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2276 MonoReflectionType *t)
2278 enumtype->type = t->type;
2281 static MonoReflectionType*
2282 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2284 MonoDynamicGenericClass *gclass;
2285 MonoReflectionType *parent = NULL;
2290 MONO_ARCH_SAVE_REGS;
2292 g_assert (type->type.type->data.generic_class->is_dynamic);
2293 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2295 domain = mono_object_domain (type);
2296 klass = mono_class_from_mono_type (type->generic_type->type);
2298 if (!klass->generic_class && !klass->generic_container)
2301 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2302 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2303 parent = tb->parent;
2304 } else if (klass->wastypebuilder) {
2305 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2306 parent = tb->parent;
2308 MonoClass *pklass = klass->parent;
2310 parent = mono_type_get_object (domain, &pklass->byval_arg);
2313 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2316 inflated = mono_class_inflate_generic_type (
2317 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2319 return mono_type_get_object (domain, inflated);
2323 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2325 static MonoClass *System_Reflection_MonoGenericClass;
2326 MonoGenericClass *gclass;
2327 MonoReflectionTypeBuilder *tb = NULL;
2328 MonoClass *klass = NULL;
2333 MONO_ARCH_SAVE_REGS;
2335 if (!System_Reflection_MonoGenericClass) {
2336 System_Reflection_MonoGenericClass = mono_class_from_name (
2337 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2338 g_assert (System_Reflection_MonoGenericClass);
2341 domain = mono_object_domain (type);
2343 gclass = type->type.type->data.generic_class;
2344 g_assert (gclass->is_dynamic);
2346 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2347 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2348 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2350 klass = gclass->container_class;
2351 mono_class_init (klass);
2352 icount = klass->interface_count;
2355 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2357 for (i = 0; i < icount; i++) {
2358 MonoReflectionType *iface;
2362 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2365 it = &klass->interfaces [i]->byval_arg;
2367 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2369 iface = mono_type_get_object (domain, it);
2370 mono_array_setref (res, i, iface);
2376 static MonoReflectionMethod*
2377 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2378 MonoReflectionMethod* generic)
2380 MonoGenericClass *gclass;
2381 MonoDynamicGenericClass *dgclass;
2385 MONO_ARCH_SAVE_REGS;
2387 gclass = type->type.type->data.generic_class;
2388 g_assert (gclass->is_dynamic);
2390 dgclass = (MonoDynamicGenericClass *) gclass;
2392 domain = mono_object_domain (type);
2394 for (i = 0; i < dgclass->count_methods; i++)
2395 if (generic->method->token == dgclass->methods [i]->token)
2396 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2401 static MonoReflectionMethod*
2402 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2403 MonoReflectionMethod* generic)
2405 MonoGenericClass *gclass;
2406 MonoDynamicGenericClass *dgclass;
2410 MONO_ARCH_SAVE_REGS;
2412 gclass = type->type.type->data.generic_class;
2413 g_assert (gclass->is_dynamic);
2415 dgclass = (MonoDynamicGenericClass *) gclass;
2417 domain = mono_object_domain (type);
2419 for (i = 0; i < dgclass->count_ctors; i++)
2420 if (generic->method->token == dgclass->ctors [i]->token)
2421 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2427 static MonoReflectionField*
2428 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2429 MonoString* generic_name)
2431 MonoGenericClass *gclass;
2432 MonoDynamicGenericClass *dgclass;
2434 MonoClass *refclass;
2435 char *utf8_name = mono_string_to_utf8 (generic_name);
2438 MONO_ARCH_SAVE_REGS;
2440 gclass = type->type.type->data.generic_class;
2441 g_assert (gclass->is_dynamic);
2443 dgclass = (MonoDynamicGenericClass *) gclass;
2445 refclass = mono_class_from_mono_type (type->type.type);
2447 domain = mono_object_domain (type);
2449 for (i = 0; i < dgclass->count_fields; i++)
2450 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2452 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2461 static MonoReflectionMethod*
2462 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2463 MonoReflectionMethod* generic)
2470 MONO_ARCH_SAVE_REGS;
2472 domain = ((MonoObject *)type)->vtable->domain;
2474 klass = mono_class_from_mono_type (type->type);
2477 while ((method = mono_class_get_methods (klass, &iter))) {
2478 if (method->token == generic->method->token)
2479 return mono_method_get_object (domain, method, klass);
2486 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2487 MonoReflectionType *reflected_type)
2489 MonoGenericClass *gclass;
2490 MonoDynamicGenericClass *dgclass;
2492 MonoClass *refclass;
2496 MONO_ARCH_SAVE_REGS;
2498 gclass = type->type.type->data.generic_class;
2499 g_assert (gclass->is_dynamic);
2500 dgclass = (MonoDynamicGenericClass *) gclass;
2502 refclass = mono_class_from_mono_type (reflected_type->type);
2504 domain = mono_object_domain (type);
2505 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2507 for (i = 0; i < dgclass->count_methods; i++)
2508 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2514 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2515 MonoReflectionType *reflected_type)
2517 static MonoClass *System_Reflection_ConstructorInfo;
2518 MonoGenericClass *gclass;
2519 MonoDynamicGenericClass *dgclass;
2521 MonoClass *refclass;
2525 MONO_ARCH_SAVE_REGS;
2527 if (!System_Reflection_ConstructorInfo)
2528 System_Reflection_ConstructorInfo = mono_class_from_name (
2529 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2531 gclass = type->type.type->data.generic_class;
2532 g_assert (gclass->is_dynamic);
2533 dgclass = (MonoDynamicGenericClass *) gclass;
2535 refclass = mono_class_from_mono_type (reflected_type->type);
2537 domain = mono_object_domain (type);
2538 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2540 for (i = 0; i < dgclass->count_ctors; i++)
2541 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2547 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2548 MonoReflectionType *reflected_type)
2550 MonoGenericClass *gclass;
2551 MonoDynamicGenericClass *dgclass;
2553 MonoClass *refclass;
2557 MONO_ARCH_SAVE_REGS;
2559 gclass = type->type.type->data.generic_class;
2560 g_assert (gclass->is_dynamic);
2561 dgclass = (MonoDynamicGenericClass *) gclass;
2563 refclass = mono_class_from_mono_type (reflected_type->type);
2565 domain = mono_object_domain (type);
2566 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2568 for (i = 0; i < dgclass->count_fields; i++)
2569 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2575 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2576 MonoReflectionType *reflected_type)
2578 static MonoClass *System_Reflection_PropertyInfo;
2579 MonoGenericClass *gclass;
2580 MonoDynamicGenericClass *dgclass;
2582 MonoClass *refclass;
2586 MONO_ARCH_SAVE_REGS;
2588 if (!System_Reflection_PropertyInfo)
2589 System_Reflection_PropertyInfo = mono_class_from_name (
2590 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2592 gclass = type->type.type->data.generic_class;
2593 g_assert (gclass->is_dynamic);
2594 dgclass = (MonoDynamicGenericClass *) gclass;
2596 refclass = mono_class_from_mono_type (reflected_type->type);
2598 domain = mono_object_domain (type);
2599 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2601 for (i = 0; i < dgclass->count_properties; i++)
2602 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2608 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2609 MonoReflectionType *reflected_type)
2611 static MonoClass *System_Reflection_EventInfo;
2612 MonoGenericClass *gclass;
2613 MonoDynamicGenericClass *dgclass;
2615 MonoClass *refclass;
2619 MONO_ARCH_SAVE_REGS;
2621 if (!System_Reflection_EventInfo)
2622 System_Reflection_EventInfo = mono_class_from_name (
2623 mono_defaults.corlib, "System.Reflection", "EventInfo");
2625 gclass = type->type.type->data.generic_class;
2626 g_assert (gclass->is_dynamic);
2627 dgclass = (MonoDynamicGenericClass *) gclass;
2629 refclass = mono_class_from_mono_type (reflected_type->type);
2631 domain = mono_object_domain (type);
2632 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2634 for (i = 0; i < dgclass->count_events; i++)
2635 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2640 static MonoReflectionMethod *
2641 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2646 MONO_ARCH_SAVE_REGS;
2648 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2651 method = type->type->data.generic_param->owner->owner.method;
2653 klass = mono_class_from_mono_type (type->type);
2654 return mono_method_get_object (mono_object_domain (type), method, klass);
2657 static MonoReflectionDllImportAttribute*
2658 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2660 static MonoClass *DllImportAttributeClass = NULL;
2661 MonoDomain *domain = mono_domain_get ();
2662 MonoReflectionDllImportAttribute *attr;
2663 MonoImage *image = method->klass->image;
2664 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2665 MonoTableInfo *tables = image->tables;
2666 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2667 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2668 guint32 im_cols [MONO_IMPLMAP_SIZE];
2669 guint32 scope_token;
2670 const char *import = NULL;
2671 const char *scope = NULL;
2674 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2677 if (!DllImportAttributeClass) {
2678 DllImportAttributeClass =
2679 mono_class_from_name (mono_defaults.corlib,
2680 "System.Runtime.InteropServices", "DllImportAttribute");
2681 g_assert (DllImportAttributeClass);
2684 if (method->klass->image->dynamic) {
2685 MonoReflectionMethodAux *method_aux =
2686 g_hash_table_lookup (
2687 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2689 import = method_aux->dllentry;
2690 scope = method_aux->dll;
2694 if (piinfo->implmap_idx) {
2695 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2697 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2698 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2699 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2700 scope = mono_metadata_string_heap (image, scope_token);
2703 flags = piinfo->piflags;
2705 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2707 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2708 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2709 attr->call_conv = (flags & 0x700) >> 8;
2710 attr->charset = ((flags & 0x6) >> 1) + 1;
2711 if (attr->charset == 1)
2713 attr->exact_spelling = (flags & 0x1) != 0;
2714 attr->set_last_error = (flags & 0x40) != 0;
2715 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2716 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2717 attr->preserve_sig = FALSE;
2722 static MonoReflectionMethod *
2723 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2725 MonoMethodInflated *imethod;
2727 MONO_ARCH_SAVE_REGS;
2729 if (method->method->generic_container)
2732 if (!method->method->is_inflated)
2735 imethod = (MonoMethodInflated *) method->method;
2737 if (imethod->reflection_info)
2738 return imethod->reflection_info;
2740 return mono_method_get_object (
2741 mono_object_domain (method), imethod->declaring, NULL);
2745 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2747 MONO_ARCH_SAVE_REGS;
2749 return mono_method_signature (method->method)->generic_param_count != 0;
2753 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2755 MONO_ARCH_SAVE_REGS;
2757 return method->method->generic_container != NULL;
2761 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2766 MONO_ARCH_SAVE_REGS;
2768 domain = mono_object_domain (method);
2770 if (method->method->is_inflated) {
2771 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2774 count = inst->type_argc;
2775 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2777 for (i = 0; i < count; i++)
2778 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2784 count = mono_method_signature (method->method)->generic_param_count;
2785 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2787 for (i = 0; i < count; i++) {
2788 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2789 MonoClass *pklass = mono_class_from_generic_parameter (
2790 param, method->method->klass->image, TRUE);
2791 mono_array_setref (res, i,
2792 mono_type_get_object (domain, &pklass->byval_arg));
2799 ensure_reflection_security (void)
2801 MonoMethod *m = mono_method_get_last_managed ();
2805 g_print ("method %s.%s.%s in image %s\n",
2806 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2809 /* We stop at the first method which is not in
2810 System.Reflection or which is not in a platform
2812 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2813 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2814 /* If the method is transparent we throw an exception. */
2815 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2816 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2818 mono_raise_exception (ex);
2823 mono_stack_walk_no_il (get_caller, &m);
2828 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2831 * Invoke from reflection is supposed to always be a virtual call (the API
2832 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2833 * greater flexibility.
2835 MonoMethod *m = method->method;
2839 MONO_ARCH_SAVE_REGS;
2841 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2842 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2843 ensure_reflection_security ();
2845 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2847 if (!mono_object_isinst (this, m->klass))
2848 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2849 m = mono_object_get_virtual_method (this, m);
2850 /* must pass the pointer to the value for valuetype methods */
2851 if (m->klass->valuetype)
2852 obj = mono_object_unbox (this);
2853 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2854 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2857 pcount = params? mono_array_length (params): 0;
2858 if (pcount != mono_method_signature (m)->param_count)
2859 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2861 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2862 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2864 if (m->klass->image->assembly->ref_only)
2865 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2867 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2870 guint32 *lower_bounds;
2871 pcount = mono_array_length (params);
2872 lengths = alloca (sizeof (guint32) * pcount);
2873 for (i = 0; i < pcount; ++i)
2874 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2876 if (m->klass->rank == pcount) {
2877 /* Only lengths provided. */
2878 lower_bounds = NULL;
2880 g_assert (pcount == (m->klass->rank * 2));
2881 /* lower bounds are first. */
2882 lower_bounds = lengths;
2883 lengths += m->klass->rank;
2886 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2888 return mono_runtime_invoke_array (m, obj, params, NULL);
2892 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2894 MonoDomain *domain = mono_object_domain (method);
2895 MonoMethod *m = method->method;
2896 MonoMethodSignature *sig = mono_method_signature (m);
2897 MonoArray *out_args;
2899 int i, j, outarg_count = 0;
2901 MONO_ARCH_SAVE_REGS;
2903 if (m->klass == mono_defaults.object_class) {
2905 if (!strcmp (m->name, "FieldGetter")) {
2906 MonoClass *k = this->vtable->klass;
2910 /* If this is a proxy, then it must be a CBO */
2911 if (k == mono_defaults.transparent_proxy_class) {
2912 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2913 this = tp->rp->unwrapped_server;
2915 k = this->vtable->klass;
2918 name = mono_array_get (params, MonoString *, 1);
2919 str = mono_string_to_utf8 (name);
2922 MonoClassField* field = mono_class_get_field_from_name (k, str);
2924 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2925 if (field_klass->valuetype)
2926 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2928 result = *((gpointer *)((char *)this + field->offset));
2930 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2931 *outArgs = out_args;
2932 mono_array_setref (out_args, 0, result);
2940 g_assert_not_reached ();
2942 } else if (!strcmp (m->name, "FieldSetter")) {
2943 MonoClass *k = this->vtable->klass;
2949 /* If this is a proxy, then it must be a CBO */
2950 if (k == mono_defaults.transparent_proxy_class) {
2951 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2952 this = tp->rp->unwrapped_server;
2954 k = this->vtable->klass;
2957 name = mono_array_get (params, MonoString *, 1);
2958 str = mono_string_to_utf8 (name);
2961 MonoClassField* field = mono_class_get_field_from_name (k, str);
2963 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2964 MonoObject *val = mono_array_get (params, gpointer, 2);
2966 if (field_klass->valuetype) {
2967 size = mono_type_size (field->type, &align);
2968 memcpy ((char *)this + field->offset,
2969 ((char *)val) + sizeof (MonoObject), size);
2971 *(MonoObject**)((char *)this + field->offset) = val;
2973 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2974 *outArgs = out_args;
2984 g_assert_not_reached ();
2989 for (i = 0; i < mono_array_length (params); i++) {
2990 if (sig->params [i]->byref)
2994 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2996 /* handle constructors only for objects already allocated */
2997 if (!strcmp (method->method->name, ".ctor"))
3000 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3001 g_assert (!method->method->klass->valuetype);
3002 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3004 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3005 if (sig->params [i]->byref) {
3007 arg = mono_array_get (params, gpointer, i);
3008 mono_array_setref (out_args, j, arg);
3013 *outArgs = out_args;
3019 read_enum_value (char *mem, int type)
3023 return *(guint8*)mem;
3025 return *(gint8*)mem;
3027 return *(guint16*)mem;
3029 return *(gint16*)mem;
3031 return *(guint32*)mem;
3033 return *(gint32*)mem;
3035 return *(guint64*)mem;
3037 return *(gint64*)mem;
3039 g_assert_not_reached ();
3045 write_enum_value (char *mem, int type, guint64 value)
3049 case MONO_TYPE_I1: {
3050 guint8 *p = (guint8*)mem;
3055 case MONO_TYPE_I2: {
3056 guint16 *p = (void*)mem;
3061 case MONO_TYPE_I4: {
3062 guint32 *p = (void*)mem;
3067 case MONO_TYPE_I8: {
3068 guint64 *p = (void*)mem;
3073 g_assert_not_reached ();
3079 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3082 MonoClass *enumc, *objc;
3086 MONO_ARCH_SAVE_REGS;
3088 MONO_CHECK_ARG_NULL (enumType);
3089 MONO_CHECK_ARG_NULL (value);
3091 domain = mono_object_domain (enumType);
3092 enumc = mono_class_from_mono_type (enumType->type);
3093 objc = value->vtable->klass;
3095 if (!enumc->enumtype)
3096 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3097 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3098 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."));
3100 res = mono_object_new (domain, enumc);
3101 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3102 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3108 ves_icall_System_Enum_get_value (MonoObject *this)
3116 MONO_ARCH_SAVE_REGS;
3121 g_assert (this->vtable->klass->enumtype);
3123 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3124 res = mono_object_new (mono_object_domain (this), enumc);
3125 dst = (char *)res + sizeof (MonoObject);
3126 src = (char *)this + sizeof (MonoObject);
3127 size = mono_class_value_size (enumc, NULL);
3129 memcpy (dst, src, size);
3135 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3137 MonoDomain *domain = mono_object_domain (type);
3138 MonoClass *enumc = mono_class_from_mono_type (type->type);
3139 guint j = 0, nvalues, crow;
3141 MonoClassField *field;
3143 MONO_ARCH_SAVE_REGS;
3145 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3146 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3147 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3148 info->values = mono_array_new (domain, enumc, nvalues);
3152 while ((field = mono_class_get_fields (enumc, &iter))) {
3156 if (strcmp ("value__", field->name) == 0)
3158 if (mono_field_is_deleted (field))
3160 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3163 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3164 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3165 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3166 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3170 len = mono_metadata_decode_blob_size (p, &p);
3171 switch (enumc->enum_basetype->type) {
3174 mono_array_set (info->values, gchar, j, *p);
3176 case MONO_TYPE_CHAR:
3179 mono_array_set (info->values, gint16, j, read16 (p));
3183 mono_array_set (info->values, gint32, j, read32 (p));
3187 mono_array_set (info->values, gint64, j, read64 (p));
3190 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3197 BFLAGS_IgnoreCase = 1,
3198 BFLAGS_DeclaredOnly = 2,
3199 BFLAGS_Instance = 4,
3201 BFLAGS_Public = 0x10,
3202 BFLAGS_NonPublic = 0x20,
3203 BFLAGS_FlattenHierarchy = 0x40,
3204 BFLAGS_InvokeMethod = 0x100,
3205 BFLAGS_CreateInstance = 0x200,
3206 BFLAGS_GetField = 0x400,
3207 BFLAGS_SetField = 0x800,
3208 BFLAGS_GetProperty = 0x1000,
3209 BFLAGS_SetProperty = 0x2000,
3210 BFLAGS_ExactBinding = 0x10000,
3211 BFLAGS_SuppressChangeType = 0x20000,
3212 BFLAGS_OptionalParamBinding = 0x40000
3215 static MonoReflectionField *
3216 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3219 MonoClass *startklass, *klass;
3221 MonoClassField *field;
3224 int (*compare_func) (const char *s1, const char *s2) = NULL;
3225 domain = ((MonoObject *)type)->vtable->domain;
3226 klass = startklass = mono_class_from_mono_type (type->type);
3228 MONO_ARCH_SAVE_REGS;
3231 mono_raise_exception (mono_get_exception_argument_null ("name"));
3232 if (type->type->byref)
3235 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3238 if (klass->exception_type != MONO_EXCEPTION_NONE)
3239 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3242 while ((field = mono_class_get_fields (klass, &iter))) {
3245 if (field->type == NULL)
3247 if (mono_field_is_deleted (field))
3249 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3250 if (bflags & BFLAGS_Public)
3253 if (bflags & BFLAGS_NonPublic)
3259 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3260 if (bflags & BFLAGS_Static)
3261 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3264 if (bflags & BFLAGS_Instance)
3271 utf8_name = mono_string_to_utf8 (name);
3273 if (compare_func (field->name, utf8_name)) {
3279 return mono_field_get_object (domain, klass, field);
3281 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3288 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3291 MonoClass *startklass, *klass, *refklass;
3296 MonoClassField *field;
3298 MONO_ARCH_SAVE_REGS;
3300 domain = ((MonoObject *)type)->vtable->domain;
3301 if (type->type->byref)
3302 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3303 klass = startklass = mono_class_from_mono_type (type->type);
3304 refklass = mono_class_from_mono_type (reftype->type);
3308 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3310 if (klass->exception_type != MONO_EXCEPTION_NONE)
3311 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3314 while ((field = mono_class_get_fields (klass, &iter))) {
3316 if (mono_field_is_deleted (field))
3318 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3319 if (bflags & BFLAGS_Public)
3322 if (bflags & BFLAGS_NonPublic) {
3323 /* Serialization currently depends on the old behavior.
3324 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3331 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3332 if (bflags & BFLAGS_Static)
3333 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3336 if (bflags & BFLAGS_Instance)
3342 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3344 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3345 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3349 mono_array_setref (res, i, member);
3352 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3355 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3356 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3359 * Better solution for the new GC.
3360 * res->max_length = i;
3367 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3370 MonoClass *startklass, *klass, *refklass;
3375 int i, len, match, nslots;
3376 guint32 method_slots_default [8];
3377 guint32 *method_slots;
3378 gchar *mname = NULL;
3379 int (*compare_func) (const char *s1, const char *s2) = NULL;
3381 MONO_ARCH_SAVE_REGS;
3383 domain = ((MonoObject *)type)->vtable->domain;
3384 if (type->type->byref)
3385 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3386 klass = startklass = mono_class_from_mono_type (type->type);
3387 refklass = mono_class_from_mono_type (reftype->type);
3390 mname = mono_string_to_utf8 (name);
3391 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3394 mono_class_setup_vtable (klass);
3396 if (is_generic_parameter (type->type))
3397 nslots = klass->parent->vtable_size;
3399 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3400 if (nslots >= sizeof (method_slots_default) * 8) {
3401 method_slots = g_new0 (guint32, nslots / 32 + 1);
3403 method_slots = method_slots_default;
3404 memset (method_slots, 0, sizeof (method_slots_default));
3408 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3410 mono_class_setup_vtable (klass);
3411 if (klass->exception_type != MONO_EXCEPTION_NONE)
3412 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3415 while ((method = mono_class_get_methods (klass, &iter))) {
3417 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3419 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3420 if (bflags & BFLAGS_Public)
3423 if (bflags & BFLAGS_NonPublic)
3429 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3430 if (bflags & BFLAGS_Static)
3431 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3434 if (bflags & BFLAGS_Instance)
3442 if (compare_func (mname, method->name))
3447 if (method->slot != -1) {
3448 g_assert (method->slot < nslots);
3449 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3451 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3454 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3457 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3458 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3462 mono_array_setref (res, i, member);
3465 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3469 if (method_slots != method_slots_default)
3470 g_free (method_slots);
3472 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3473 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3476 * Better solution for the new GC.
3477 * res->max_length = i;
3484 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3487 static MonoClass *System_Reflection_ConstructorInfo;
3488 MonoClass *startklass, *klass, *refklass;
3493 gpointer iter = NULL;
3495 MONO_ARCH_SAVE_REGS;
3497 domain = ((MonoObject *)type)->vtable->domain;
3498 if (type->type->byref)
3499 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3500 klass = startklass = mono_class_from_mono_type (type->type);
3501 refklass = mono_class_from_mono_type (reftype->type);
3503 if (klass->exception_type != MONO_EXCEPTION_NONE)
3504 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3506 if (!System_Reflection_ConstructorInfo)
3507 System_Reflection_ConstructorInfo = mono_class_from_name (
3508 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3512 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3514 while ((method = mono_class_get_methods (klass, &iter))) {
3516 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3518 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3519 if (bflags & BFLAGS_Public)
3522 if (bflags & BFLAGS_NonPublic)
3528 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3529 if (bflags & BFLAGS_Static)
3530 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3533 if (bflags & BFLAGS_Instance)
3539 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3542 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3543 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3547 mono_array_setref (res, i, member);
3551 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3552 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3555 * Better solution for the new GC.
3556 * res->max_length = i;
3563 property_hash (gconstpointer data)
3565 MonoProperty *prop = (MonoProperty*)data;
3567 return g_str_hash (prop->name);
3571 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3573 // Properties are hide-by-name-and-signature
3574 if (!g_str_equal (prop1->name, prop2->name))
3577 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3579 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3585 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3590 switch (accessor->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3591 case METHOD_ATTRIBUTE_ASSEM:
3592 return (start_klass || mono_defaults.generic_ilist_class);
3594 case METHOD_ATTRIBUTE_PRIVATE:
3596 case METHOD_ATTRIBUTE_PUBLIC:
3604 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3607 static MonoClass *System_Reflection_PropertyInfo;
3608 MonoClass *startklass, *klass;
3615 gchar *propname = NULL;
3616 int (*compare_func) (const char *s1, const char *s2) = NULL;
3618 GHashTable *properties;
3620 MONO_ARCH_SAVE_REGS;
3622 if (!System_Reflection_PropertyInfo)
3623 System_Reflection_PropertyInfo = mono_class_from_name (
3624 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3626 domain = ((MonoObject *)type)->vtable->domain;
3627 if (type->type->byref)
3628 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3629 klass = startklass = mono_class_from_mono_type (type->type);
3631 propname = mono_string_to_utf8 (name);
3632 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3635 mono_class_setup_vtable (klass);
3637 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3640 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3642 mono_class_setup_vtable (klass);
3643 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3644 g_hash_table_destroy (properties);
3647 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3651 while ((prop = mono_class_get_properties (klass, &iter))) {
3657 flags = method->flags;
3660 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3661 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3662 if (bflags & BFLAGS_Public)
3664 } else if (bflags & BFLAGS_NonPublic) {
3665 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3666 property_accessor_nonpublic(prop->set, startklass == klass)) {
3673 if (flags & METHOD_ATTRIBUTE_STATIC) {
3674 if (bflags & BFLAGS_Static)
3675 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3678 if (bflags & BFLAGS_Instance)
3687 if (compare_func (propname, prop->name))
3691 if (g_hash_table_lookup (properties, prop))
3695 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3696 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3700 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3703 g_hash_table_insert (properties, prop, prop);
3705 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3708 g_hash_table_destroy (properties);
3711 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3712 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3715 * Better solution for the new GC.
3716 * res->max_length = i;
3722 static MonoReflectionEvent *
3723 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3726 MonoClass *klass, *startklass;
3732 MONO_ARCH_SAVE_REGS;
3734 event_name = mono_string_to_utf8 (name);
3735 if (type->type->byref)
3737 klass = startklass = mono_class_from_mono_type (type->type);
3738 domain = mono_object_domain (type);
3741 if (klass->exception_type != MONO_EXCEPTION_NONE)
3742 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3745 while ((event = mono_class_get_events (klass, &iter))) {
3746 if (strcmp (event->name, event_name))
3749 method = event->add;
3751 method = event->remove;
3753 method = event->raise;
3755 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3756 if (!(bflags & BFLAGS_Public))
3759 if (!(bflags & BFLAGS_NonPublic))
3764 if (!(bflags & BFLAGS_NonPublic))
3767 g_free (event_name);
3768 return mono_event_get_object (domain, startklass, event);
3771 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3774 g_free (event_name);
3779 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3782 static MonoClass *System_Reflection_EventInfo;
3783 MonoClass *startklass, *klass;
3790 MONO_ARCH_SAVE_REGS;
3792 if (!System_Reflection_EventInfo)
3793 System_Reflection_EventInfo = mono_class_from_name (
3794 mono_defaults.corlib, "System.Reflection", "EventInfo");
3796 domain = mono_object_domain (type);
3797 if (type->type->byref)
3798 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3799 klass = startklass = mono_class_from_mono_type (type->type);
3803 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3805 if (klass->exception_type != MONO_EXCEPTION_NONE)
3806 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3809 while ((event = mono_class_get_events (klass, &iter))) {
3811 method = event->add;
3813 method = event->remove;
3815 method = event->raise;
3817 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3818 if (bflags & BFLAGS_Public)
3821 if (bflags & BFLAGS_NonPublic)
3826 if (bflags & BFLAGS_NonPublic)
3832 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3833 if (bflags & BFLAGS_Static)
3834 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3837 if (bflags & BFLAGS_Instance)
3842 if (bflags & BFLAGS_Instance)
3848 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3849 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3853 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3856 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3859 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3860 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3863 * Better solution for the new GC.
3864 * res->max_length = i;
3870 static MonoReflectionType *
3871 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3879 MONO_ARCH_SAVE_REGS;
3881 domain = ((MonoObject *)type)->vtable->domain;
3882 if (type->type->byref)
3884 klass = mono_class_from_mono_type (type->type);
3885 str = mono_string_to_utf8 (name);
3888 if (klass->exception_type != MONO_EXCEPTION_NONE)
3889 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3892 * If a nested type is generic, return its generic type definition.
3893 * Note that this means that the return value is essentially a
3894 * nested type of the generic type definition of @klass.
3896 * A note in MSDN claims that a generic type definition can have
3897 * nested types that aren't generic. In any case, the container of that
3898 * nested type would be the generic type definition.
3900 if (klass->generic_class)
3901 klass = klass->generic_class->container_class;
3903 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3905 nested = tmpn->data;
3906 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3907 if (bflags & BFLAGS_Public)
3910 if (bflags & BFLAGS_NonPublic)
3915 if (strcmp (nested->name, str) == 0){
3917 return mono_type_get_object (domain, &nested->byval_arg);
3920 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3927 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3937 MONO_ARCH_SAVE_REGS;
3939 domain = ((MonoObject *)type)->vtable->domain;
3940 if (type->type->byref)
3941 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3942 klass = mono_class_from_mono_type (type->type);
3943 if (klass->exception_type != MONO_EXCEPTION_NONE)
3944 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3947 * If a nested type is generic, return its generic type definition.
3948 * Note that this means that the return value is essentially the set
3949 * of nested types of the generic type definition of @klass.
3951 * A note in MSDN claims that a generic type definition can have
3952 * nested types that aren't generic. In any case, the container of that
3953 * nested type would be the generic type definition.
3955 if (klass->generic_class)
3956 klass = klass->generic_class->container_class;
3960 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3961 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3963 nested = tmpn->data;
3964 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3965 if (bflags & BFLAGS_Public)
3968 if (bflags & BFLAGS_NonPublic)
3973 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3975 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3976 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3980 mono_array_setref (res, i, member);
3984 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3985 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3988 * Better solution for the new GC.
3989 * res->max_length = i;
3995 static MonoReflectionType*
3996 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3999 MonoType *type = NULL;
4000 MonoTypeNameParse info;
4001 gboolean type_resolve;
4003 MONO_ARCH_SAVE_REGS;
4005 /* On MS.NET, this does not fire a TypeResolve event */
4006 type_resolve = TRUE;
4007 str = mono_string_to_utf8 (name);
4008 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4009 if (!mono_reflection_parse_type (str, &info)) {
4011 mono_reflection_free_type_info (&info);
4012 if (throwOnError) /* uhm: this is a parse error, though... */
4013 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4014 /*g_print ("failed parse\n");*/
4018 if (info.assembly.name) {
4020 /* 1.0 and 2.0 throw different exceptions */
4021 if (mono_defaults.generic_ilist_class)
4022 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4024 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4029 if (module != NULL) {
4031 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4036 if (assembly->assembly->dynamic) {
4037 /* Enumerate all modules */
4038 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4042 if (abuilder->modules) {
4043 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4044 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4045 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4051 if (!type && abuilder->loaded_modules) {
4052 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4053 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4054 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4061 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4063 mono_reflection_free_type_info (&info);
4065 MonoException *e = NULL;
4068 e = mono_get_exception_type_load (name, NULL);
4070 mono_loader_clear_error ();
4073 mono_raise_exception (e);
4078 if (type->type == MONO_TYPE_CLASS) {
4079 MonoClass *klass = mono_type_get_class (type);
4080 /* need to report exceptions ? */
4081 if (throwOnError && klass->exception_type) {
4082 /* report SecurityException (or others) that occured when loading the assembly */
4083 MonoException *exc = mono_class_get_exception_for_failure (klass);
4084 mono_loader_clear_error ();
4085 mono_raise_exception (exc);
4086 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4091 /* g_print ("got it\n"); */
4092 return mono_type_get_object (mono_object_domain (assembly), type);
4096 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4098 MonoDomain *domain = mono_object_domain (assembly);
4099 MonoAssembly *mass = assembly->assembly;
4100 MonoString *res = NULL;
4104 MONO_ARCH_SAVE_REGS;
4106 if (g_path_is_absolute (mass->image->name))
4107 absolute = g_strdup (mass->image->name);
4109 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4113 for (i = strlen (absolute) - 1; i >= 0; i--)
4114 if (absolute [i] == '\\')
4119 uri = g_filename_to_uri (absolute, NULL, NULL);
4121 uri = g_strconcat ("file://", absolute, NULL);
4125 res = mono_string_new (domain, uri);
4133 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4135 MonoAssembly *mass = assembly->assembly;
4137 MONO_ARCH_SAVE_REGS;
4139 return mass->in_gac;
4142 static MonoReflectionAssembly*
4143 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4147 MonoImageOpenStatus status;
4149 MONO_ARCH_SAVE_REGS;
4151 name = mono_string_to_utf8 (mname);
4152 res = mono_assembly_load_with_partial_name (name, &status);
4158 return mono_assembly_get_object (mono_domain_get (), res);
4162 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4164 MonoDomain *domain = mono_object_domain (assembly);
4167 MONO_ARCH_SAVE_REGS;
4169 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4175 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4177 MONO_ARCH_SAVE_REGS;
4179 return assembly->assembly->ref_only;
4183 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4185 MonoDomain *domain = mono_object_domain (assembly);
4187 MONO_ARCH_SAVE_REGS;
4189 return mono_string_new (domain, assembly->assembly->image->version);
4192 static MonoReflectionMethod*
4193 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4195 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4197 MONO_ARCH_SAVE_REGS;
4201 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4204 static MonoReflectionModule*
4205 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4207 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4211 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4213 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4214 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4218 MONO_ARCH_SAVE_REGS;
4220 for (i = 0; i < table->rows; ++i) {
4221 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4222 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4228 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4230 static MonoClass *System_Version = NULL;
4231 static MonoMethod *create_version = NULL;
4235 if (!System_Version) {
4236 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4237 g_assert (System_Version);
4240 if (!create_version) {
4241 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4242 create_version = mono_method_desc_search_in_class (desc, System_Version);
4243 g_assert (create_version);
4244 mono_method_desc_free (desc);
4250 args [3] = &revision;
4251 result = mono_object_new (domain, System_Version);
4252 mono_runtime_invoke (create_version, result, args, NULL);
4258 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4260 static MonoClass *System_Reflection_AssemblyName;
4262 MonoDomain *domain = mono_object_domain (assembly);
4264 static MonoMethod *create_culture = NULL;
4265 MonoImage *image = assembly->assembly->image;
4268 MONO_ARCH_SAVE_REGS;
4270 if (!System_Reflection_AssemblyName)
4271 System_Reflection_AssemblyName = mono_class_from_name (
4272 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4274 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4277 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4280 MonoMethodDesc *desc = mono_method_desc_new (
4281 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4282 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4283 g_assert (create_culture);
4284 mono_method_desc_free (desc);
4287 for (i = 0; i < count; i++) {
4288 MonoReflectionAssemblyName *aname;
4289 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4291 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4293 aname = (MonoReflectionAssemblyName *) mono_object_new (
4294 domain, System_Reflection_AssemblyName);
4296 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4298 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4299 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4300 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4301 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4302 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4303 aname->versioncompat = 1; /* SameMachine (default) */
4304 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4305 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4307 if (create_culture) {
4309 gboolean assembly_ref = TRUE;
4310 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4311 args [1] = &assembly_ref;
4312 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4315 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4316 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4317 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4319 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4320 /* public key token isn't copied - the class library will
4321 automatically generate it from the public key if required */
4322 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4323 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4325 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4326 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4330 /* note: this function doesn't return the codebase on purpose (i.e. it can
4331 be used under partial trust as path information isn't present). */
4333 mono_array_setref (result, i, aname);
4344 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4346 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4348 mono_array_setref (info->res, info->idx, name);
4353 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4355 MonoImage *img = assembly->assembly->image;
4359 MONO_ARCH_SAVE_REGS;
4361 if (!img->name_cache)
4362 mono_image_init_name_cache (img);
4364 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4367 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4372 /* move this in some file in mono/util/ */
4374 g_concat_dir_and_file (const char *dir, const char *file)
4376 g_return_val_if_fail (dir != NULL, NULL);
4377 g_return_val_if_fail (file != NULL, NULL);
4380 * If the directory name doesn't have a / on the end, we need
4381 * to add one so we get a proper path to the file
4383 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4384 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4386 return g_strconcat (dir, file, NULL);
4390 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4392 char *n = mono_string_to_utf8 (name);
4393 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4395 guint32 cols [MONO_MANIFEST_SIZE];
4396 guint32 impl, file_idx;
4400 MONO_ARCH_SAVE_REGS;
4402 for (i = 0; i < table->rows; ++i) {
4403 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4404 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4405 if (strcmp (val, n) == 0)
4409 if (i == table->rows)
4412 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4415 * this code should only be called after obtaining the
4416 * ResourceInfo and handling the other cases.
4418 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4419 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4421 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4426 module = assembly->assembly->image;
4428 *ref_module = mono_module_get_object (mono_domain_get (), module);
4430 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4434 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4436 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4438 guint32 cols [MONO_MANIFEST_SIZE];
4439 guint32 file_cols [MONO_FILE_SIZE];
4443 MONO_ARCH_SAVE_REGS;
4445 n = mono_string_to_utf8 (name);
4446 for (i = 0; i < table->rows; ++i) {
4447 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4448 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4449 if (strcmp (val, n) == 0)
4453 if (i == table->rows)
4456 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4457 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4460 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4461 case MONO_IMPLEMENTATION_FILE:
4462 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4463 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4464 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4465 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4466 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4467 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4470 info->location = RESOURCE_LOCATION_EMBEDDED;
4473 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4474 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4475 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4476 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4477 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4478 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4480 mono_raise_exception (ex);
4482 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4484 /* Obtain info recursively */
4485 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4486 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4489 case MONO_IMPLEMENTATION_EXP_TYPE:
4490 g_assert_not_reached ();
4499 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4501 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4502 MonoArray *result = NULL;
4507 MONO_ARCH_SAVE_REGS;
4509 /* check hash if needed */
4511 n = mono_string_to_utf8 (name);
4512 for (i = 0; i < table->rows; ++i) {
4513 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4514 if (strcmp (val, n) == 0) {
4517 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4518 fn = mono_string_new (mono_object_domain (assembly), n);
4520 return (MonoObject*)fn;
4528 for (i = 0; i < table->rows; ++i) {
4529 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4533 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4536 for (i = 0; i < table->rows; ++i) {
4537 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4538 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4539 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4540 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4545 return (MonoObject*)result;
4549 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4551 MonoDomain *domain = mono_domain_get();
4554 int i, j, file_count = 0;
4555 MonoImage **modules;
4556 guint32 module_count, real_module_count;
4557 MonoTableInfo *table;
4559 g_assert (assembly->assembly->image != NULL);
4561 if (assembly->assembly->dynamic) {
4562 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4564 if (assemblyb->modules)
4565 module_count = mono_array_length (assemblyb->modules);
4568 real_module_count = module_count;
4570 modules = g_new0 (MonoImage*, module_count);
4571 if (assemblyb->modules) {
4572 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4574 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4579 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4580 file_count = table->rows;
4582 modules = assembly->assembly->image->modules;
4583 module_count = assembly->assembly->image->module_count;
4585 real_module_count = 0;
4586 for (i = 0; i < module_count; ++i)
4588 real_module_count ++;
4591 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4592 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4594 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4596 for (i = 0; i < module_count; ++i)
4598 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4602 for (i = 0; i < file_count; ++i, ++j)
4603 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4605 if (assembly->assembly->dynamic)
4611 static MonoReflectionMethod*
4612 ves_icall_GetCurrentMethod (void)
4614 MonoMethod *m = mono_method_get_last_managed ();
4616 MONO_ARCH_SAVE_REGS;
4618 return mono_method_get_object (mono_domain_get (), m, NULL);
4621 static MonoReflectionMethod*
4622 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4624 /* FIXME check that method belongs to klass or a parent */
4627 klass = mono_class_from_mono_type (type);
4629 klass = method->klass;
4630 return mono_method_get_object (mono_domain_get (), method, klass);
4633 static MonoReflectionMethod*
4634 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4636 return mono_method_get_object (mono_domain_get (), method, NULL);
4639 static MonoReflectionMethodBody*
4640 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4642 return mono_method_body_get_object (mono_domain_get (), method);
4645 static MonoReflectionAssembly*
4646 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4648 MonoMethod *m = mono_method_get_last_managed ();
4650 MONO_ARCH_SAVE_REGS;
4652 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4656 static MonoReflectionAssembly*
4657 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4659 MonoDomain* domain = mono_domain_get ();
4661 MONO_ARCH_SAVE_REGS;
4663 if (!domain->entry_assembly)
4666 return mono_assembly_get_object (domain, domain->entry_assembly);
4669 static MonoReflectionAssembly*
4670 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4672 MonoMethod *m = mono_method_get_last_managed ();
4673 MonoMethod *dest = m;
4675 MONO_ARCH_SAVE_REGS;
4677 mono_stack_walk_no_il (get_caller, &dest);
4680 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4684 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4685 gboolean assembly_qualified)
4687 MonoDomain *domain = mono_object_domain (object);
4688 MonoTypeNameFormat format;
4692 MONO_ARCH_SAVE_REGS;
4694 format = assembly_qualified ?
4695 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4696 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4698 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4700 name = mono_type_get_name_full (object->type, format);
4704 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4709 res = mono_string_new (domain, name);
4716 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4718 static MonoMethod *create_culture = NULL;
4721 const char *pkey_ptr;
4723 gboolean assembly_ref = FALSE;
4725 MONO_ARCH_SAVE_REGS;
4727 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4728 aname->major = name->major;
4729 aname->minor = name->minor;
4730 aname->build = name->build;
4731 aname->revision = name->revision;
4732 aname->hashalg = name->hash_alg;
4733 if (by_default_version)
4734 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4736 codebase = g_filename_to_uri (absolute, NULL, NULL);
4738 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4742 if (!create_culture) {
4743 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4744 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4745 g_assert (create_culture);
4746 mono_method_desc_free (desc);
4749 if (name->culture) {
4750 args [0] = mono_string_new (domain, name->culture);
4751 args [1] = &assembly_ref;
4752 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4755 if (name->public_key) {
4756 pkey_ptr = (char*)name->public_key;
4757 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4759 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4760 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4763 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4764 if (name->public_key_token [0]) {
4768 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4769 p = mono_array_addr (aname->keyToken, char, 0);
4771 for (i = 0, j = 0; i < 8; i++) {
4772 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4773 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4780 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4783 MonoAssembly *mass = assembly->assembly;
4785 MONO_ARCH_SAVE_REGS;
4787 if (g_path_is_absolute (mass->image->name)) {
4788 fill_reflection_assembly_name (mono_object_domain (assembly),
4789 aname, &mass->aname, mass->image->name, TRUE);
4792 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4794 fill_reflection_assembly_name (mono_object_domain (assembly),
4795 aname, &mass->aname, absolute, TRUE);
4801 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4804 MonoImageOpenStatus status = MONO_IMAGE_OK;
4807 MonoAssemblyName name;
4809 MONO_ARCH_SAVE_REGS;
4811 filename = mono_string_to_utf8 (fname);
4813 image = mono_image_open (filename, &status);
4819 if (status == MONO_IMAGE_IMAGE_INVALID)
4820 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4822 exc = mono_get_exception_file_not_found2 (NULL, fname);
4823 mono_raise_exception (exc);
4826 res = mono_assembly_fill_assembly_name (image, &name);
4828 mono_image_close (image);
4830 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4833 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4836 mono_image_close (image);
4840 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4841 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4843 MonoBoolean result = FALSE;
4844 MonoDeclSecurityEntry entry;
4846 /* SecurityAction.RequestMinimum */
4847 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4848 *minimum = entry.blob;
4849 *minLength = entry.size;
4852 /* SecurityAction.RequestOptional */
4853 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4854 *optional = entry.blob;
4855 *optLength = entry.size;
4858 /* SecurityAction.RequestRefuse */
4859 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4860 *refused = entry.blob;
4861 *refLength = entry.size;
4869 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4873 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4875 guint32 attrs, visibility;
4877 /* we start the count from 1 because we skip the special type <Module> */
4880 for (i = 1; i < tdef->rows; ++i) {
4881 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4882 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4883 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4887 count = tdef->rows - 1;
4889 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4891 for (i = 1; i < tdef->rows; ++i) {
4892 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4893 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4894 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4895 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4896 if (mono_loader_get_last_error ())
4897 mono_loader_clear_error ();
4898 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4907 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4909 MonoArray *res = NULL;
4910 MonoImage *image = NULL;
4911 MonoTableInfo *table = NULL;
4916 MONO_ARCH_SAVE_REGS;
4918 domain = mono_object_domain (assembly);
4920 if (assembly->assembly->dynamic) {
4921 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4922 if (abuilder->modules) {
4923 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4924 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4925 MonoArray *append = mb->types;
4926 /* The types array might not be fully filled up */
4927 if (append && mb->num_types > 0) {
4930 len1 = res ? mono_array_length (res) : 0;
4931 len2 = mb->num_types;
4932 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4934 mono_array_memcpy_refs (new, 0, res, 0, len1);
4935 mono_array_memcpy_refs (new, len1, append, 0, len2);
4941 * Replace TypeBuilders with the created types to be compatible
4945 for (i = 0; i < mono_array_length (res); ++i) {
4946 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4948 mono_array_setref (res, i, tb->created);
4953 if (abuilder->loaded_modules)
4954 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4955 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4956 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4957 if (append && mono_array_length (append) > 0) {
4960 len1 = res ? mono_array_length (res) : 0;
4961 len2 = mono_array_length (append);
4962 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4964 mono_array_memcpy_refs (new, 0, res, 0, len1);
4965 mono_array_memcpy_refs (new, len1, append, 0, len2);
4972 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4974 image = assembly->assembly->image;
4975 table = &image->tables [MONO_TABLE_FILE];
4976 res = mono_module_get_types (domain, image, exportedOnly);
4978 /* Append data from all modules in the assembly */
4979 for (i = 0; i < table->rows; ++i) {
4980 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4981 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4983 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4984 /* Append the new types to the end of the array */
4985 if (mono_array_length (res2) > 0) {
4989 len1 = mono_array_length (res);
4990 len2 = mono_array_length (res2);
4991 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4992 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4993 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5000 /* the ReflectionTypeLoadException must have all the types (Types property),
5001 * NULL replacing types which throws an exception. The LoaderException must
5002 * contain all exceptions for NULL items.
5005 len = mono_array_length (res);
5007 for (i = 0; i < len; i++) {
5008 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5009 MonoClass *klass = mono_type_get_class (t->type);
5010 if ((klass != NULL) && klass->exception_type) {
5011 /* keep the class in the list */
5012 list = g_list_append (list, klass);
5013 /* and replace Type with NULL */
5014 mono_array_setref (res, i, NULL);
5020 MonoException *exc = NULL;
5021 MonoArray *exl = NULL;
5022 int length = g_list_length (list);
5024 mono_loader_clear_error ();
5026 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5027 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5028 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5029 mono_array_setref (exl, i, exc);
5034 exc = mono_get_exception_reflection_type_load (res, exl);
5035 mono_loader_clear_error ();
5036 mono_raise_exception (exc);
5043 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5045 MonoAssemblyName aname;
5046 MonoDomain *domain = mono_object_domain (name);
5048 gboolean is_version_defined;
5050 val = mono_string_to_utf8 (assname);
5051 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
5054 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
5056 mono_assembly_name_free (&aname);
5057 g_free ((guint8*) aname.public_key);
5063 static MonoReflectionType*
5064 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5066 MonoDomain *domain = mono_object_domain (module);
5069 MONO_ARCH_SAVE_REGS;
5071 g_assert (module->image);
5073 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5074 /* These images do not have a global type */
5077 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5078 return mono_type_get_object (domain, &klass->byval_arg);
5082 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5084 /*if (module->image)
5085 mono_image_close (module->image);*/
5089 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5091 MonoDomain *domain = mono_object_domain (module);
5093 MONO_ARCH_SAVE_REGS;
5095 g_assert (module->image);
5096 return mono_string_new (domain, module->image->guid);
5100 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5102 if (image->dynamic) {
5103 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5104 *pe_kind = dyn->pe_kind;
5105 *machine = dyn->machine;
5108 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5109 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5114 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5116 return (image->md_version_major << 16) | (image->md_version_minor);
5120 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5122 MONO_ARCH_SAVE_REGS;
5125 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5127 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5131 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5133 guint32 cols [MONO_MEMBERREF_SIZE];
5135 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5136 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5137 mono_metadata_decode_blob_size (sig, &sig);
5138 return (*sig != 0x6);
5142 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5145 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5146 mono_array_addr (type_args, MonoType*, 0));
5148 context->class_inst = NULL;
5150 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5151 mono_array_addr (method_args, MonoType*, 0));
5153 context->method_inst = NULL;
5157 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5160 int table = mono_metadata_token_table (token);
5161 int index = mono_metadata_token_index (token);
5162 MonoGenericContext context;
5164 *error = ResolveTokenError_Other;
5166 /* Validate token */
5167 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5168 (table != MONO_TABLE_TYPESPEC)) {
5169 *error = ResolveTokenError_BadTable;
5173 if (image->dynamic) {
5174 if (type_args || method_args)
5175 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5176 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5179 if ((index <= 0) || (index > image->tables [table].rows)) {
5180 *error = ResolveTokenError_OutOfRange;
5184 init_generic_context_from_args (&context, type_args, method_args);
5185 klass = mono_class_get_full (image, token, &context);
5188 return &klass->byval_arg;
5194 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5196 int table = mono_metadata_token_table (token);
5197 int index = mono_metadata_token_index (token);
5198 MonoGenericContext context;
5201 *error = ResolveTokenError_Other;
5203 /* Validate token */
5204 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5205 (table != MONO_TABLE_MEMBERREF)) {
5206 *error = ResolveTokenError_BadTable;
5210 if (image->dynamic) {
5211 if (type_args || method_args)
5212 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5213 /* FIXME: validate memberref token type */
5214 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5217 if ((index <= 0) || (index > image->tables [table].rows)) {
5218 *error = ResolveTokenError_OutOfRange;
5221 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5222 *error = ResolveTokenError_BadTable;
5226 init_generic_context_from_args (&context, type_args, method_args);
5227 method = mono_get_method_full (image, token, NULL, &context);
5233 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5235 int index = mono_metadata_token_index (token);
5237 *error = ResolveTokenError_Other;
5239 /* Validate token */
5240 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5241 *error = ResolveTokenError_BadTable;
5246 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5248 if ((index <= 0) || (index >= image->heap_us.size)) {
5249 *error = ResolveTokenError_OutOfRange;
5253 /* FIXME: What to do if the index points into the middle of a string ? */
5255 return mono_ldstr (mono_domain_get (), image, index);
5258 static MonoClassField*
5259 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5262 int table = mono_metadata_token_table (token);
5263 int index = mono_metadata_token_index (token);
5264 MonoGenericContext context;
5265 MonoClassField *field;
5267 *error = ResolveTokenError_Other;
5269 /* Validate token */
5270 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5271 *error = ResolveTokenError_BadTable;
5275 if (image->dynamic) {
5276 if (type_args || method_args)
5277 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5278 /* FIXME: validate memberref token type */
5279 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5282 if ((index <= 0) || (index > image->tables [table].rows)) {
5283 *error = ResolveTokenError_OutOfRange;
5286 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5287 *error = ResolveTokenError_BadTable;
5291 init_generic_context_from_args (&context, type_args, method_args);
5292 field = mono_field_from_token (image, token, &klass, &context);
5299 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5301 int table = mono_metadata_token_table (token);
5303 *error = ResolveTokenError_Other;
5306 case MONO_TABLE_TYPEDEF:
5307 case MONO_TABLE_TYPEREF:
5308 case MONO_TABLE_TYPESPEC: {
5309 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5311 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5315 case MONO_TABLE_METHOD:
5316 case MONO_TABLE_METHODSPEC: {
5317 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5319 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5323 case MONO_TABLE_FIELD: {
5324 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5326 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5330 case MONO_TABLE_MEMBERREF:
5331 if (mono_metadata_memberref_is_method (image, token)) {
5332 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5334 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5339 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5341 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5348 *error = ResolveTokenError_BadTable;
5355 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5357 int table = mono_metadata_token_table (token);
5358 int idx = mono_metadata_token_index (token);
5359 MonoTableInfo *tables = image->tables;
5364 *error = ResolveTokenError_OutOfRange;
5366 /* FIXME: Support other tables ? */
5367 if (table != MONO_TABLE_STANDALONESIG)
5373 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5376 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5378 ptr = mono_metadata_blob_heap (image, sig);
5379 len = mono_metadata_decode_blob_size (ptr, &ptr);
5381 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5382 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5386 static MonoReflectionType*
5387 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5390 int isbyref = 0, rank;
5391 char *str = mono_string_to_utf8 (smodifiers);
5394 MONO_ARCH_SAVE_REGS;
5396 klass = mono_class_from_mono_type (tb->type.type);
5398 /* logic taken from mono_reflection_parse_type(): keep in sync */
5402 if (isbyref) { /* only one level allowed by the spec */
5409 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5412 klass = mono_ptr_class_get (&klass->byval_arg);
5413 mono_class_init (klass);
5424 else if (*p != '*') { /* '*' means unknown lower bound */
5435 klass = mono_array_class_get (klass, rank);
5436 mono_class_init (klass);
5443 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5447 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5452 MONO_ARCH_SAVE_REGS;
5455 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5460 static MonoReflectionType *
5461 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5463 MonoClass *klass, *aklass;
5465 MONO_ARCH_SAVE_REGS;
5467 klass = mono_class_from_mono_type (type->type);
5468 aklass = mono_array_class_get (klass, rank);
5470 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5473 static MonoReflectionType *
5474 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5478 MONO_ARCH_SAVE_REGS;
5480 klass = mono_class_from_mono_type (type->type);
5482 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5485 static MonoReflectionType *
5486 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5490 MONO_ARCH_SAVE_REGS;
5492 pklass = mono_ptr_class_get (type->type);
5494 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5498 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5499 MonoReflectionMethod *info)
5501 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5502 MonoObject *delegate;
5505 MONO_ARCH_SAVE_REGS;
5507 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5509 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5511 if (info->method->dynamic)
5512 /* Creating a trampoline would leak memory */
5513 func = mono_compile_method (info->method);
5515 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5517 mono_delegate_ctor (delegate, target, func);
5523 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5525 /* Reset the invoke impl to the default one */
5526 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5530 * Magic number to convert a time which is relative to
5531 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5533 #define EPOCH_ADJUST ((guint64)62135596800LL)
5536 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5538 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5541 * This returns Now in UTC
5544 ves_icall_System_DateTime_GetNow (void)
5546 #ifdef PLATFORM_WIN32
5550 GetSystemTime (&st);
5551 SystemTimeToFileTime (&st, &ft);
5552 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5554 /* FIXME: put this in io-layer and call it GetLocalTime */
5558 MONO_ARCH_SAVE_REGS;
5560 if (gettimeofday (&tv, NULL) == 0) {
5561 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5564 /* fixme: raise exception */
5569 #ifdef PLATFORM_WIN32
5570 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5572 convert_to_absolute_date(SYSTEMTIME *date)
5574 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5575 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5576 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5577 /* from the calendar FAQ */
5578 int a = (14 - date->wMonth) / 12;
5579 int y = date->wYear - a;
5580 int m = date->wMonth + 12 * a - 2;
5581 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5583 /* d is now the day of the week for the first of the month (0 == Sunday) */
5585 int day_of_week = date->wDayOfWeek;
5587 /* set day_in_month to the first day in the month which falls on day_of_week */
5588 int day_in_month = 1 + (day_of_week - d);
5589 if (day_in_month <= 0)
5592 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5593 date->wDay = day_in_month + (date->wDay - 1) * 7;
5594 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5599 #ifndef PLATFORM_WIN32
5601 * Return's the offset from GMT of a local time.
5603 * tm is a local time
5604 * t is the same local time as seconds.
5607 gmt_offset(struct tm *tm, time_t t)
5609 #if defined (HAVE_TM_GMTOFF)
5610 return tm->tm_gmtoff;
5615 g.tm_isdst = tm->tm_isdst;
5617 return (int)difftime(t, t2);
5622 * This is heavily based on zdump.c from glibc 2.2.
5624 * * data[0]: start of daylight saving time (in DateTime ticks).
5625 * * data[1]: end of daylight saving time (in DateTime ticks).
5626 * * data[2]: utcoffset (in TimeSpan ticks).
5627 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5628 * * name[0]: name of this timezone when not daylight saving.
5629 * * name[1]: name of this timezone when daylight saving.
5631 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5632 * the class library allows years between 1 and 9999.
5634 * Returns true on success and zero on failure.
5637 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5639 #ifndef PLATFORM_WIN32
5640 MonoDomain *domain = mono_domain_get ();
5641 struct tm start, tt;
5645 int is_daylight = 0, day;
5648 MONO_ARCH_SAVE_REGS;
5650 MONO_CHECK_ARG_NULL (data);
5651 MONO_CHECK_ARG_NULL (names);
5653 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5654 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5657 * no info is better than crashing: we'll need our own tz data
5658 * to make this work properly, anyway. The range is probably
5659 * reduced to 1970 .. 2037 because that is what mktime is
5660 * guaranteed to support (we get into an infinite loop
5664 memset (&start, 0, sizeof (start));
5667 start.tm_year = year-1900;
5669 t = mktime (&start);
5671 if ((year < 1970) || (year > 2037) || (t == -1)) {
5673 tt = *localtime (&t);
5674 strftime (tzone, sizeof (tzone), "%Z", &tt);
5675 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5676 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5680 gmtoff = gmt_offset (&start, t);
5682 /* For each day of the year, calculate the tm_gmtoff. */
5683 for (day = 0; day < 365; day++) {
5686 tt = *localtime (&t);
5688 /* Daylight saving starts or ends here. */
5689 if (gmt_offset (&tt, t) != gmtoff) {
5693 /* Try to find the exact hour when daylight saving starts/ends. */
5697 tt1 = *localtime (&t1);
5698 } while (gmt_offset (&tt1, t1) != gmtoff);
5700 /* Try to find the exact minute when daylight saving starts/ends. */
5703 tt1 = *localtime (&t1);
5704 } while (gmt_offset (&tt1, t1) == gmtoff);
5706 strftime (tzone, sizeof (tzone), "%Z", &tt);
5708 /* Write data, if we're already in daylight saving, we're done. */
5710 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5711 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5714 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5715 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5719 /* This is only set once when we enter daylight saving. */
5720 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5721 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5723 gmtoff = gmt_offset (&tt, t);
5728 strftime (tzone, sizeof (tzone), "%Z", &tt);
5729 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5730 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5731 mono_array_set ((*data), gint64, 0, 0);
5732 mono_array_set ((*data), gint64, 1, 0);
5733 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5734 mono_array_set ((*data), gint64, 3, 0);
5739 MonoDomain *domain = mono_domain_get ();
5740 TIME_ZONE_INFORMATION tz_info;
5745 tz_id = GetTimeZoneInformation (&tz_info);
5746 if (tz_id == TIME_ZONE_ID_INVALID)
5749 MONO_CHECK_ARG_NULL (data);
5750 MONO_CHECK_ARG_NULL (names);
5752 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5753 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5755 for (i = 0; i < 32; ++i)
5756 if (!tz_info.DaylightName [i])
5758 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5759 for (i = 0; i < 32; ++i)
5760 if (!tz_info.StandardName [i])
5762 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5764 if ((year <= 1601) || (year > 30827)) {
5766 * According to MSDN, the MS time functions can't handle dates outside
5772 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5773 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5774 tz_info.StandardDate.wYear = year;
5775 convert_to_absolute_date(&tz_info.StandardDate);
5776 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5781 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5782 tz_info.DaylightDate.wYear = year;
5783 convert_to_absolute_date(&tz_info.DaylightDate);
5784 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5789 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5791 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5792 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5799 ves_icall_System_Object_obj_address (MonoObject *this)
5801 MONO_ARCH_SAVE_REGS;
5808 static inline gint32
5809 mono_array_get_byte_length (MonoArray *array)
5815 klass = array->obj.vtable->klass;
5817 if (array->bounds == NULL)
5818 length = array->max_length;
5821 for (i = 0; i < klass->rank; ++ i)
5822 length *= array->bounds [i].length;
5825 switch (klass->element_class->byval_arg.type) {
5828 case MONO_TYPE_BOOLEAN:
5832 case MONO_TYPE_CHAR:
5840 return length * sizeof (gpointer);
5851 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5853 MONO_ARCH_SAVE_REGS;
5855 return mono_array_get_byte_length (array);
5859 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5861 MONO_ARCH_SAVE_REGS;
5863 return mono_array_get (array, gint8, idx);
5867 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5869 MONO_ARCH_SAVE_REGS;
5871 mono_array_set (array, gint8, idx, value);
5875 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5877 guint8 *src_buf, *dest_buf;
5879 MONO_ARCH_SAVE_REGS;
5881 /* watch out for integer overflow */
5882 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5885 src_buf = (guint8 *)src->vector + src_offset;
5886 dest_buf = (guint8 *)dest->vector + dest_offset;
5889 memcpy (dest_buf, src_buf, count);
5891 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5897 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5899 MonoDomain *domain = mono_object_domain (this);
5901 MonoRealProxy *rp = ((MonoRealProxy *)this);
5902 MonoTransparentProxy *tp;
5906 MONO_ARCH_SAVE_REGS;
5908 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5909 tp = (MonoTransparentProxy*) res;
5911 MONO_OBJECT_SETREF (tp, rp, rp);
5912 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5913 klass = mono_class_from_mono_type (type);
5915 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5916 tp->remote_class = mono_remote_class (domain, class_name, klass);
5918 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5922 static MonoReflectionType *
5923 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5925 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5928 /* System.Environment */
5931 ves_icall_System_Environment_get_MachineName (void)
5933 #if defined (PLATFORM_WIN32)
5938 len = MAX_COMPUTERNAME_LENGTH + 1;
5939 buf = g_new (gunichar2, len);
5942 if (GetComputerName (buf, (PDWORD) &len))
5943 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5951 if (gethostname (buf, sizeof (buf)) == 0)
5952 result = mono_string_new (mono_domain_get (), buf);
5961 ves_icall_System_Environment_get_Platform (void)
5963 MONO_ARCH_SAVE_REGS;
5965 #if defined (PLATFORM_WIN32)
5975 ves_icall_System_Environment_get_NewLine (void)
5977 MONO_ARCH_SAVE_REGS;
5979 #if defined (PLATFORM_WIN32)
5980 return mono_string_new (mono_domain_get (), "\r\n");
5982 return mono_string_new (mono_domain_get (), "\n");
5987 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5992 MONO_ARCH_SAVE_REGS;
5997 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5998 value = g_getenv (utf8_name);
6005 return mono_string_new (mono_domain_get (), value);
6009 * There is no standard way to get at environ.
6012 #ifndef __MINGW32_VERSION
6019 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6021 #ifdef PLATFORM_WIN32
6030 env_strings = GetEnvironmentStrings();
6033 env_string = env_strings;
6034 while (*env_string != '\0') {
6035 /* weird case that MS seems to skip */
6036 if (*env_string != '=')
6038 while (*env_string != '\0')
6044 domain = mono_domain_get ();
6045 names = mono_array_new (domain, mono_defaults.string_class, n);
6049 env_string = env_strings;
6050 while (*env_string != '\0') {
6051 /* weird case that MS seems to skip */
6052 if (*env_string != '=') {
6053 equal_str = wcschr(env_string, '=');
6054 g_assert(equal_str);
6055 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6056 mono_array_setref (names, n, str);
6059 while (*env_string != '\0')
6064 FreeEnvironmentStrings (env_strings);
6076 MONO_ARCH_SAVE_REGS;
6079 for (e = environ; *e != 0; ++ e)
6082 domain = mono_domain_get ();
6083 names = mono_array_new (domain, mono_defaults.string_class, n);
6086 for (e = environ; *e != 0; ++ e) {
6087 parts = g_strsplit (*e, "=", 2);
6089 str = mono_string_new (domain, *parts);
6090 mono_array_setref (names, n, str);
6103 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6105 #if !GLIB_CHECK_VERSION(2,4,0)
6106 #define g_setenv(a,b,c) setenv(a,b,c)
6107 #define g_unsetenv(a) unsetenv(a)
6111 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6113 #ifdef PLATFORM_WIN32
6114 gunichar2 *utf16_name, *utf16_value;
6116 gchar *utf8_name, *utf8_value;
6119 MONO_ARCH_SAVE_REGS;
6121 #ifdef PLATFORM_WIN32
6122 utf16_name = mono_string_to_utf16 (name);
6123 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6124 SetEnvironmentVariable (utf16_name, NULL);
6125 g_free (utf16_name);
6129 utf16_value = mono_string_to_utf16 (value);
6131 SetEnvironmentVariable (utf16_name, utf16_value);
6133 g_free (utf16_name);
6134 g_free (utf16_value);
6136 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6138 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6139 g_unsetenv (utf8_name);
6144 utf8_value = mono_string_to_utf8 (value);
6145 g_setenv (utf8_name, utf8_value, TRUE);
6148 g_free (utf8_value);
6153 * Returns: the number of milliseconds elapsed since the system started.
6156 ves_icall_System_Environment_get_TickCount (void)
6158 return GetTickCount ();
6163 ves_icall_System_Environment_Exit (int result)
6165 MONO_ARCH_SAVE_REGS;
6167 if (!mono_threads_set_shutting_down (TRUE))
6170 mono_runtime_set_shutting_down ();
6172 /* Suspend all managed threads since the runtime is going away */
6173 mono_thread_suspend_all_other_threads ();
6175 mono_runtime_quit ();
6177 /* we may need to do some cleanup here... */
6182 ves_icall_System_Environment_GetGacPath (void)
6184 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6188 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6190 #if defined (PLATFORM_WIN32)
6191 #ifndef CSIDL_FLAG_CREATE
6192 #define CSIDL_FLAG_CREATE 0x8000
6195 WCHAR path [MAX_PATH];
6196 /* Create directory if no existing */
6197 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6201 return mono_string_new_utf16 (mono_domain_get (), path, len);
6204 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6206 return mono_string_new (mono_domain_get (), "");
6210 ves_icall_System_Environment_GetLogicalDrives (void)
6212 gunichar2 buf [128], *ptr, *dname;
6214 gint initial_size = 127, size = 128;
6217 MonoString *drivestr;
6218 MonoDomain *domain = mono_domain_get ();
6221 MONO_ARCH_SAVE_REGS;
6226 while (size > initial_size) {
6227 size = GetLogicalDriveStrings (initial_size, ptr);
6228 if (size > initial_size) {
6231 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6232 initial_size = size;
6246 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6251 while (*u16) { u16++; len ++; }
6252 drivestr = mono_string_new_utf16 (domain, dname, len);
6253 mono_array_setref (result, ndrives++, drivestr);
6264 ves_icall_System_Environment_InternalGetHome (void)
6266 MONO_ARCH_SAVE_REGS;
6268 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6271 static const char *encodings [] = {
6273 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6274 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6275 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6277 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6278 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6279 "x_unicode_2_0_utf_7",
6281 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6282 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6284 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6287 "unicodefffe", "utf_16be",
6294 * Returns the internal codepage, if the value of "int_code_page" is
6295 * 1 at entry, and we can not compute a suitable code page number,
6296 * returns the code page as a string
6299 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6304 char *codepage = NULL;
6306 int want_name = *int_code_page;
6309 *int_code_page = -1;
6310 MONO_ARCH_SAVE_REGS;
6312 g_get_charset (&cset);
6313 c = codepage = strdup (cset);
6314 for (c = codepage; *c; c++){
6315 if (isascii (*c) && isalpha (*c))
6320 /* g_print ("charset: %s\n", cset); */
6322 /* handle some common aliases */
6325 for (i = 0; p != 0; ){
6326 if ((gssize) p < 7){
6328 p = encodings [++i];
6331 if (strcmp (p, codepage) == 0){
6332 *int_code_page = code;
6335 p = encodings [++i];
6338 if (strstr (codepage, "utf_8") != NULL)
6339 *int_code_page |= 0x10000000;
6342 if (want_name && *int_code_page == -1)
6343 return mono_string_new (mono_domain_get (), cset);
6349 ves_icall_System_Environment_get_HasShutdownStarted (void)
6351 if (mono_runtime_is_shutting_down ())
6354 if (mono_domain_is_unloading (mono_domain_get ()))
6361 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6362 MonoReflectionMethod *method,
6363 MonoArray *out_args)
6365 MONO_ARCH_SAVE_REGS;
6367 mono_message_init (mono_object_domain (this), this, method, out_args);
6371 ves_icall_IsTransparentProxy (MonoObject *proxy)
6373 MONO_ARCH_SAVE_REGS;
6378 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6384 static MonoReflectionMethod *
6385 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6386 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6390 MonoMethod **vtable;
6391 MonoMethod *res = NULL;
6393 MONO_CHECK_ARG_NULL (rtype);
6394 MONO_CHECK_ARG_NULL (rmethod);
6396 method = rmethod->method;
6397 klass = mono_class_from_mono_type (rtype->type);
6399 if (MONO_CLASS_IS_INTERFACE (klass))
6402 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6405 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6406 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6412 mono_class_setup_vtable (klass);
6413 vtable = klass->vtable;
6415 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6416 int offs = mono_class_interface_offset (klass, method->klass);
6418 res = vtable [offs + method->slot];
6420 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6423 if (method->slot != -1)
6424 res = vtable [method->slot];
6430 return mono_method_get_object (mono_domain_get (), res, NULL);
6434 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6439 MONO_ARCH_SAVE_REGS;
6441 klass = mono_class_from_mono_type (type->type);
6442 vtable = mono_class_vtable (mono_domain_get (), klass);
6444 if (enable) vtable->remote = 1;
6445 else vtable->remote = 0;
6449 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6454 MONO_ARCH_SAVE_REGS;
6456 domain = mono_object_domain (type);
6457 klass = mono_class_from_mono_type (type->type);
6459 if (klass->rank >= 1) {
6460 g_assert (klass->rank == 1);
6461 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6463 /* Bypass remoting object creation check */
6464 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6469 ves_icall_System_IO_get_temp_path (void)
6471 MONO_ARCH_SAVE_REGS;
6473 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6477 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6479 MONO_ARCH_SAVE_REGS;
6481 return mono_compile_method (method);
6485 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6490 MONO_ARCH_SAVE_REGS;
6492 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6494 #if defined (PLATFORM_WIN32)
6495 /* Avoid mixing '/' and '\\' */
6498 for (i = strlen (path) - 1; i >= 0; i--)
6499 if (path [i] == '/')
6503 mcpath = mono_string_new (mono_domain_get (), path);
6510 get_bundled_machine_config (void)
6512 const gchar *machine_config;
6514 MONO_ARCH_SAVE_REGS;
6516 machine_config = mono_get_machine_config ();
6518 if (!machine_config)
6521 return mono_string_new (mono_domain_get (), machine_config);
6525 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6530 MONO_ARCH_SAVE_REGS;
6532 path = g_path_get_dirname (mono_get_config_dir ());
6534 #if defined (PLATFORM_WIN32)
6535 /* Avoid mixing '/' and '\\' */
6538 for (i = strlen (path) - 1; i >= 0; i--)
6539 if (path [i] == '/')
6543 ipath = mono_string_new (mono_domain_get (), path);
6550 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6552 #if defined (PLATFORM_WIN32)
6553 OutputDebugString (mono_string_chars (message));
6555 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6559 /* Only used for value types */
6561 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6566 MONO_ARCH_SAVE_REGS;
6568 domain = mono_object_domain (type);
6569 klass = mono_class_from_mono_type (type->type);
6571 if (mono_class_is_nullable (klass))
6572 /* No arguments -> null */
6575 return mono_object_new (domain, klass);
6578 static MonoReflectionMethod *
6579 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6581 MonoClass *klass, *parent;
6582 MonoMethod *method = m->method;
6583 MonoMethod *result = NULL;
6585 MONO_ARCH_SAVE_REGS;
6587 if (method->klass == NULL)
6590 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6591 MONO_CLASS_IS_INTERFACE (method->klass) ||
6592 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6595 klass = method->klass;
6596 if (klass->generic_class)
6597 klass = klass->generic_class->container_class;
6599 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6600 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6601 mono_class_setup_vtable (parent);
6602 if (parent->vtable_size <= method->slot)
6607 if (klass == method->klass)
6610 result = klass->vtable [method->slot];
6611 if (result == NULL) {
6612 /* It is an abstract method */
6613 gpointer iter = NULL;
6614 while ((result = mono_class_get_methods (klass, &iter)))
6615 if (result->slot == method->slot)
6622 return mono_method_get_object (mono_domain_get (), result, NULL);
6626 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6628 MonoMethod *method = m->method;
6630 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6635 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6637 MONO_ARCH_SAVE_REGS;
6639 iter->sig = *(MonoMethodSignature**)argsp;
6641 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6642 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6645 /* FIXME: it's not documented what start is exactly... */
6649 guint32 i, arg_size;
6651 iter->args = argsp + sizeof (gpointer);
6652 #ifndef MONO_ARCH_REGPARMS
6653 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6654 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6655 iter->args = (char*)iter->args + arg_size;
6659 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6661 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6665 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6667 guint32 i, arg_size;
6670 MONO_ARCH_SAVE_REGS;
6672 i = iter->sig->sentinelpos + iter->next_arg;
6674 g_assert (i < iter->sig->param_count);
6676 res.type = iter->sig->params [i];
6677 res.klass = mono_class_from_mono_type (res.type);
6678 /* FIXME: endianess issue... */
6679 res.value = iter->args;
6680 arg_size = mono_type_stack_size (res.type, &align);
6681 iter->args = (char*)iter->args + arg_size;
6684 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6690 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6692 guint32 i, arg_size;
6695 MONO_ARCH_SAVE_REGS;
6697 i = iter->sig->sentinelpos + iter->next_arg;
6699 g_assert (i < iter->sig->param_count);
6701 while (i < iter->sig->param_count) {
6702 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6704 res.type = iter->sig->params [i];
6705 res.klass = mono_class_from_mono_type (res.type);
6706 /* FIXME: endianess issue... */
6707 res.value = iter->args;
6708 arg_size = mono_type_stack_size (res.type, &align);
6709 iter->args = (char*)iter->args + arg_size;
6711 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6714 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6723 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6726 MONO_ARCH_SAVE_REGS;
6728 i = iter->sig->sentinelpos + iter->next_arg;
6730 g_assert (i < iter->sig->param_count);
6732 return iter->sig->params [i];
6736 mono_TypedReference_ToObject (MonoTypedRef tref)
6738 MONO_ARCH_SAVE_REGS;
6740 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6741 MonoObject** objp = tref.value;
6745 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6749 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6751 MONO_ARCH_SAVE_REGS;
6753 if (MONO_TYPE_IS_REFERENCE (type)) {
6754 MonoObject** objp = value;
6758 return mono_value_box (mono_domain_get (), klass, value);
6762 prelink_method (MonoMethod *method)
6764 const char *exc_class, *exc_arg;
6765 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6767 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6769 mono_raise_exception(
6770 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6772 /* create the wrapper, too? */
6776 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6778 MONO_ARCH_SAVE_REGS;
6779 prelink_method (method->method);
6783 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6785 MonoClass *klass = mono_class_from_mono_type (type->type);
6787 gpointer iter = NULL;
6788 MONO_ARCH_SAVE_REGS;
6790 while ((m = mono_class_get_methods (klass, &iter)))
6794 /* These parameters are "readonly" in corlib/System/Char.cs */
6796 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6797 guint8 const **numeric_data,
6798 gdouble const **numeric_data_values,
6799 guint16 const **to_lower_data_low,
6800 guint16 const **to_lower_data_high,
6801 guint16 const **to_upper_data_low,
6802 guint16 const **to_upper_data_high)
6804 *category_data = CategoryData;
6805 *numeric_data = NumericData;
6806 *numeric_data_values = NumericDataValues;
6807 *to_lower_data_low = ToLowerDataLow;
6808 *to_lower_data_high = ToLowerDataHigh;
6809 *to_upper_data_low = ToUpperDataLow;
6810 *to_upper_data_high = ToUpperDataHigh;
6814 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6816 return method->method->token;
6820 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6821 * and avoid useless allocations.
6824 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6828 for (i = 0; i < type->num_mods; ++i) {
6829 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6834 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6836 for (i = 0; i < type->num_mods; ++i) {
6837 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6838 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6839 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6847 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6849 MonoType *type = param->ClassImpl->type;
6850 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6851 MonoImage *image = method->method->klass->image;
6852 int pos = param->PositionImpl;
6853 MonoMethodSignature *sig = mono_method_signature (method->method);
6857 type = sig->params [pos];
6859 return type_array_from_modifiers (image, type, optional);
6863 get_property_type (MonoProperty *prop)
6865 MonoMethodSignature *sig;
6867 sig = mono_method_signature (prop->get);
6869 } else if (prop->set) {
6870 sig = mono_method_signature (prop->set);
6871 return sig->params [sig->param_count - 1];
6877 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6879 MonoType *type = get_property_type (property->property);
6880 MonoImage *image = property->klass->image;
6884 return type_array_from_modifiers (image, type, optional);
6888 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6890 MonoCustomAttrInfo *cinfo;
6893 cinfo = mono_reflection_get_custom_attrs_info (obj);
6896 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6898 mono_custom_attrs_free (cinfo);
6903 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6905 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6907 if (mono_loader_get_last_error ()) {
6908 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6909 g_assert_not_reached ();
6916 GCHandle_CheckCurrentDomain (guint32 gchandle)
6918 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6922 ves_icall_Mono_Runtime_GetDisplayName (void)
6924 static const char display_name_str [] = "Mono " VERSION;
6925 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6926 return display_name;
6931 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6932 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6933 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6934 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6935 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6936 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6937 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6938 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6942 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6947 gunichar2 last, prev_last;
6955 last = prev_last = 0;
6956 for (i = 0; i < ilength; i++) {
6958 if (c >= sizeof (dbase64)) {
6959 exc = mono_exception_from_name_msg (mono_get_corlib (),
6960 "System", "FormatException",
6961 "Invalid character found.");
6962 mono_raise_exception (exc);
6963 } else if (isspace (c)) {
6971 olength = ilength - ignored;
6973 if (allowWhitespaceOnly && olength == 0) {
6974 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6977 if ((olength & 3) != 0 || olength <= 0) {
6978 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6979 "FormatException", "Invalid length.");
6980 mono_raise_exception (exc);
6983 olength = (olength * 3) / 4;
6987 if (prev_last == '=')
6990 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6991 res_ptr = mono_array_addr (result, guchar, 0);
6992 for (i = 0; i < ilength; ) {
6995 for (k = 0; k < 4 && i < ilength;) {
7001 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7002 exc = mono_exception_from_name_msg (mono_get_corlib (),
7003 "System", "FormatException",
7004 "Invalid character found.");
7005 mono_raise_exception (exc);
7010 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7012 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7014 *res_ptr++ = (b [2] << 6) | b [3];
7016 while (i < ilength && isspace (start [i]))
7024 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7026 MONO_ARCH_SAVE_REGS;
7028 return base64_to_byte_array (mono_string_chars (str),
7029 mono_string_length (str), allowWhitespaceOnly);
7033 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7035 MONO_ARCH_SAVE_REGS;
7037 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7041 #define ICALL_TYPE(id,name,first)
7042 #define ICALL(id,name,func) Icall_ ## id,
7045 #include "metadata/icall-def.h"
7051 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7052 #define ICALL(id,name,func)
7054 #include "metadata/icall-def.h"
7060 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7061 #define ICALL(id,name,func)
7063 guint16 first_icall;
7066 static const IcallTypeDesc
7067 icall_type_descs [] = {
7068 #include "metadata/icall-def.h"
7072 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7075 #define ICALL_TYPE(id,name,first)
7078 #ifdef HAVE_ARRAY_ELEM_INIT
7079 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7080 #define MSGSTRFIELD1(line) str##line
7082 static const struct msgstrtn_t {
7083 #define ICALL(id,name,func)
7085 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7086 #include "metadata/icall-def.h"
7088 } icall_type_names_str = {
7089 #define ICALL_TYPE(id,name,first) (name),
7090 #include "metadata/icall-def.h"
7093 static const guint16 icall_type_names_idx [] = {
7094 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7095 #include "metadata/icall-def.h"
7098 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7100 static const struct msgstr_t {
7102 #define ICALL_TYPE(id,name,first)
7103 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7104 #include "metadata/icall-def.h"
7106 } icall_names_str = {
7107 #define ICALL(id,name,func) (name),
7108 #include "metadata/icall-def.h"
7111 static const guint16 icall_names_idx [] = {
7112 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7113 #include "metadata/icall-def.h"
7116 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7122 #define ICALL_TYPE(id,name,first) name,
7123 #define ICALL(id,name,func)
7124 static const char* const
7125 icall_type_names [] = {
7126 #include "metadata/icall-def.h"
7130 #define icall_type_name_get(id) (icall_type_names [(id)])
7134 #define ICALL_TYPE(id,name,first)
7135 #define ICALL(id,name,func) name,
7136 static const char* const
7138 #include "metadata/icall-def.h"
7141 #define icall_name_get(id) icall_names [(id)]
7143 #endif /* !HAVE_ARRAY_ELEM_INIT */
7147 #define ICALL_TYPE(id,name,first)
7148 #define ICALL(id,name,func) func,
7149 static const gconstpointer
7150 icall_functions [] = {
7151 #include "metadata/icall-def.h"
7155 static GHashTable *icall_hash = NULL;
7156 static GHashTable *jit_icall_hash_name = NULL;
7157 static GHashTable *jit_icall_hash_addr = NULL;
7160 mono_icall_init (void)
7164 /* check that tables are sorted: disable in release */
7167 const char *prev_class = NULL;
7168 const char *prev_method;
7170 for (i = 0; i < Icall_type_num; ++i) {
7171 const IcallTypeDesc *desc;
7174 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7175 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7176 prev_class = icall_type_name_get (i);
7177 desc = &icall_type_descs [i];
7178 num_icalls = icall_desc_num_icalls (desc);
7179 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7180 for (j = 0; j < num_icalls; ++j) {
7181 const char *methodn = icall_name_get (desc->first_icall + j);
7182 if (prev_method && strcmp (prev_method, methodn) >= 0)
7183 g_print ("method %s should come before method %s\n", methodn, prev_method);
7184 prev_method = methodn;
7189 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7193 mono_icall_cleanup (void)
7195 g_hash_table_destroy (icall_hash);
7196 g_hash_table_destroy (jit_icall_hash_name);
7197 g_hash_table_destroy (jit_icall_hash_addr);
7201 mono_add_internal_call (const char *name, gconstpointer method)
7203 mono_loader_lock ();
7205 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7207 mono_loader_unlock ();
7210 #ifdef HAVE_ARRAY_ELEM_INIT
7212 compare_method_imap (const void *key, const void *elem)
7214 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7215 return strcmp (key, method_name);
7219 find_method_icall (const IcallTypeDesc *imap, const char *name)
7221 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7224 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7228 compare_class_imap (const void *key, const void *elem)
7230 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7231 return strcmp (key, class_name);
7234 static const IcallTypeDesc*
7235 find_class_icalls (const char *name)
7237 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7240 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7245 compare_method_imap (const void *key, const void *elem)
7247 const char** method_name = (const char**)elem;
7248 return strcmp (key, *method_name);
7252 find_method_icall (const IcallTypeDesc *imap, const char *name)
7254 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7257 return (gpointer)icall_functions [(nameslot - icall_names)];
7261 compare_class_imap (const void *key, const void *elem)
7263 const char** class_name = (const char**)elem;
7264 return strcmp (key, *class_name);
7267 static const IcallTypeDesc*
7268 find_class_icalls (const char *name)
7270 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7273 return &icall_type_descs [nameslot - icall_type_names];
7279 * we should probably export this as an helper (handle nested types).
7280 * Returns the number of chars written in buf.
7283 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7285 int nspacelen, cnamelen;
7286 nspacelen = strlen (klass->name_space);
7287 cnamelen = strlen (klass->name);
7288 if (nspacelen + cnamelen + 2 > bufsize)
7291 memcpy (buf, klass->name_space, nspacelen);
7292 buf [nspacelen ++] = '.';
7294 memcpy (buf + nspacelen, klass->name, cnamelen);
7295 buf [nspacelen + cnamelen] = 0;
7296 return nspacelen + cnamelen;
7300 mono_lookup_internal_call (MonoMethod *method)
7305 int typelen = 0, mlen, siglen;
7307 const IcallTypeDesc *imap;
7309 g_assert (method != NULL);
7311 if (method->is_inflated)
7312 method = ((MonoMethodInflated *) method)->declaring;
7314 if (method->klass->nested_in) {
7315 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7319 mname [pos++] = '/';
7322 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7328 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7333 imap = find_class_icalls (mname);
7335 mname [typelen] = ':';
7336 mname [typelen + 1] = ':';
7338 mlen = strlen (method->name);
7339 memcpy (mname + typelen + 2, method->name, mlen);
7340 sigstart = mname + typelen + 2 + mlen;
7343 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7344 siglen = strlen (tmpsig);
7345 if (typelen + mlen + siglen + 6 > sizeof (mname))
7348 memcpy (sigstart + 1, tmpsig, siglen);
7349 sigstart [siglen + 1] = ')';
7350 sigstart [siglen + 2] = 0;
7353 mono_loader_lock ();
7355 res = g_hash_table_lookup (icall_hash, mname);
7357 mono_loader_unlock ();
7360 /* try without signature */
7362 res = g_hash_table_lookup (icall_hash, mname);
7364 mono_loader_unlock ();
7368 /* it wasn't found in the static call tables */
7370 mono_loader_unlock ();
7373 res = find_method_icall (imap, sigstart - mlen);
7375 mono_loader_unlock ();
7378 /* try _with_ signature */
7380 res = find_method_icall (imap, sigstart - mlen);
7382 mono_loader_unlock ();
7386 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7387 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7388 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7389 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7390 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");
7391 g_print ("If you see other errors or faults after this message they are probably related\n");
7392 g_print ("and you need to fix your mono install first.\n");
7394 mono_loader_unlock ();
7400 type_from_typename (char *typename)
7402 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7404 if (!strcmp (typename, "int"))
7405 klass = mono_defaults.int_class;
7406 else if (!strcmp (typename, "ptr"))
7407 klass = mono_defaults.int_class;
7408 else if (!strcmp (typename, "void"))
7409 klass = mono_defaults.void_class;
7410 else if (!strcmp (typename, "int32"))
7411 klass = mono_defaults.int32_class;
7412 else if (!strcmp (typename, "uint32"))
7413 klass = mono_defaults.uint32_class;
7414 else if (!strcmp (typename, "int8"))
7415 klass = mono_defaults.sbyte_class;
7416 else if (!strcmp (typename, "uint8"))
7417 klass = mono_defaults.byte_class;
7418 else if (!strcmp (typename, "int16"))
7419 klass = mono_defaults.int16_class;
7420 else if (!strcmp (typename, "uint16"))
7421 klass = mono_defaults.uint16_class;
7422 else if (!strcmp (typename, "long"))
7423 klass = mono_defaults.int64_class;
7424 else if (!strcmp (typename, "ulong"))
7425 klass = mono_defaults.uint64_class;
7426 else if (!strcmp (typename, "float"))
7427 klass = mono_defaults.single_class;
7428 else if (!strcmp (typename, "double"))
7429 klass = mono_defaults.double_class;
7430 else if (!strcmp (typename, "object"))
7431 klass = mono_defaults.object_class;
7432 else if (!strcmp (typename, "obj"))
7433 klass = mono_defaults.object_class;
7436 g_assert_not_reached ();
7438 return &klass->byval_arg;
7441 MonoMethodSignature*
7442 mono_create_icall_signature (const char *sigstr)
7447 MonoMethodSignature *res;
7449 mono_loader_lock ();
7450 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7452 mono_loader_unlock ();
7456 parts = g_strsplit (sigstr, " ", 256);
7465 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7468 #ifdef PLATFORM_WIN32
7470 * Under windows, the default pinvoke calling convention is STDCALL but
7473 res->call_convention = MONO_CALL_C;
7476 res->ret = type_from_typename (parts [0]);
7477 for (i = 1; i < len; ++i) {
7478 res->params [i - 1] = type_from_typename (parts [i]);
7483 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7485 mono_loader_unlock ();
7491 mono_find_jit_icall_by_name (const char *name)
7493 MonoJitICallInfo *info;
7494 g_assert (jit_icall_hash_name);
7496 mono_loader_lock ();
7497 info = g_hash_table_lookup (jit_icall_hash_name, name);
7498 mono_loader_unlock ();
7503 mono_find_jit_icall_by_addr (gconstpointer addr)
7505 MonoJitICallInfo *info;
7506 g_assert (jit_icall_hash_addr);
7508 mono_loader_lock ();
7509 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7510 mono_loader_unlock ();
7516 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7518 mono_loader_lock ();
7519 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7520 mono_loader_unlock ();
7524 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7526 MonoJitICallInfo *info;
7531 mono_loader_lock ();
7533 if (!jit_icall_hash_name) {
7534 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7535 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7538 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7539 g_warning ("jit icall already defined \"%s\"\n", name);
7540 g_assert_not_reached ();
7543 info = g_new0 (MonoJitICallInfo, 1);
7550 info->wrapper = func;
7552 info->wrapper = NULL;
7555 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7556 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7558 mono_loader_unlock ();