X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ficall.c;h=24c8accbc41618ed943ff799b18feea554d1afec;hb=55070096807205df9af4a724646c9f8a08bbc3e3;hp=09f7658db209a7511127411acfa7708ddeec0e56;hpb=9b235bf40954c9cabef8c4e0fb08b18748dc8881;p=mono.git diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 09f7658db20..24c8accbc41 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -24,7 +24,7 @@ #ifdef HAVE_UNISTD_H #include #endif -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) #include #endif @@ -67,72 +67,42 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) #include #include #endif #include "decimal.h" +extern MonoString* ves_icall_System_Environment_GetOSVersionString (void) MONO_INTERNAL; + static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void); static MonoArray* type_array_from_modifiers (MonoImage *image, MonoType *type, int optional); -/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes. - * It works by allocating an initial small array on stack and only going to malloc'd memory if needed. - */ -typedef struct { - void **data; - int size; - int capacity; -} MonoPtrArray; - -#define MONO_PTR_ARRAY_MAX_ON_STACK (16) - -#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\ - (ARRAY).size = 0; \ - (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \ - (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \ -} while (0) - -#define mono_ptr_array_destroy(ARRAY) do {\ - if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \ - mono_gc_free_fixed ((ARRAY).data); \ -} while (0) - -#define mono_ptr_array_append(ARRAY, VALUE) do { \ - if ((ARRAY).size >= (ARRAY).capacity) {\ - void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \ - memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \ - if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \ - mono_gc_free_fixed ((ARRAY).data); \ - (ARRAY).data = __tmp; \ - (ARRAY).capacity *= 2;\ - }\ - ((ARRAY).data [(ARRAY).size++] = VALUE); \ -} while (0) - -#define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \ - ((ARRAY).data [(IDX)] = VALUE); \ -} while (0) - -#define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)]) - -#define mono_ptr_array_size(ARRAY) ((ARRAY).size) - - static inline MonoBoolean is_generic_parameter (MonoType *type) { return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR); } +static void +mono_class_init_or_throw (MonoClass *klass) +{ + if (!mono_class_init (klass)) + mono_raise_exception (mono_class_get_exception_for_failure (klass)); +} + /* * We expect a pointer to a char, not a string */ @@ -257,6 +227,11 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 ea = (gpointer*)((char*)this->vector + (pos * esize)); va = (gpointer*)((char*)value + sizeof (MonoObject)); + if (mono_class_is_nullable (ec)) { + mono_nullable_init ((guint8*)ea, value, ec); + return; + } + if (!value) { memset (ea, 0, esize); return; @@ -547,9 +522,9 @@ ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value, static MonoArray * ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds) { - MonoClass *aklass; + MonoClass *aklass, *klass; MonoArray *array; - mono_array_size_t *sizes, i; + uintptr_t *sizes, i; gboolean bounded = FALSE; MONO_ARCH_SAVE_REGS; @@ -565,15 +540,18 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray * if (mono_array_get (lengths, gint32, i) < 0) mono_raise_exception (mono_get_exception_argument_out_of_range (NULL)); + klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0)) /* vectors are not the same as one dimensional arrays with no-zero bounds */ bounded = TRUE; else bounded = FALSE; - aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded); + aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded); - sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2); + sizes = alloca (aklass->rank * sizeof(intptr_t) * 2); for (i = 0; i < aklass->rank; ++i) { sizes [i] = mono_array_get (lengths, guint32, i); if (bounds) @@ -582,7 +560,7 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray * sizes [i + aklass->rank] = 0; } - array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank); + array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank); return array; } @@ -590,9 +568,9 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray * static MonoArray * ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds) { - MonoClass *aklass; + MonoClass *aklass, *klass; MonoArray *array; - mono_array_size_t *sizes, i; + uintptr_t *sizes, i; gboolean bounded = FALSE; MONO_ARCH_SAVE_REGS; @@ -609,15 +587,18 @@ ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) mono_raise_exception (mono_get_exception_argument_out_of_range (NULL)); + klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0)) /* vectors are not the same as one dimensional arrays with no-zero bounds */ bounded = TRUE; else bounded = FALSE; - aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded); + aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded); - sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2); + sizes = alloca (aklass->rank * sizeof(intptr_t) * 2); for (i = 0; i < aklass->rank; ++i) { sizes [i] = mono_array_get (lengths, guint64, i); if (bounds) @@ -626,7 +607,7 @@ ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray sizes [i + aklass->rank] = 0; } - array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank); + array = mono_array_new_full (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank); return array; } @@ -643,7 +624,7 @@ static gint32 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension) { gint32 rank = ((MonoObject *)this)->vtable->klass->rank; - mono_array_size_t length; + uintptr_t length; MONO_ARCH_SAVE_REGS; @@ -719,6 +700,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d if (source->bounds || dest->bounds) return FALSE; + /* there's no integer overflow since mono_array_length returns an unsigned integer */ if ((dest_idx + length > mono_array_length (dest)) || (source_idx + length > mono_array_length (source))) return FALSE; @@ -829,9 +811,11 @@ ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpoin mono_gc_wbarrier_generic_store (ea, *(gpointer*)value); } else { g_assert (ec->inited); + g_assert (esize == mono_class_value_size (ec, NULL)); if (ec->has_references) mono_gc_wbarrier_value_copy (ea, value, 1, ec); - memcpy (ea, value, esize); + else + memcpy (ea, value, esize); } } @@ -941,16 +925,17 @@ static void ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle) { MonoClass *klass; - - MONO_ARCH_SAVE_REGS; + MonoVTable *vtable; MONO_CHECK_ARG_NULL (handle); klass = mono_class_from_mono_type (handle); MONO_CHECK_ARG (handle, klass); + vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE); + /* This will call the type constructor */ - mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass)); + mono_runtime_class_init (vtable); } static void @@ -961,10 +946,34 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (M mono_image_check_for_module_cctor (image); if (image->has_module_cctor) { MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1); - mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass)); + /*It's fine to raise the exception here*/ + mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE)); } } +static MonoBoolean +ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void) +{ + guint8 *stack_addr; + guint8 *current; + size_t stack_size; + /* later make this configurable and per-arch */ + int min_size = 4096 * 4 * sizeof (void*); + mono_thread_get_stack_bounds (&stack_addr, &stack_size); + /* if we have no info we are optimistic and assume there is enough room */ + if (!stack_addr) + return TRUE; + current = (guint8 *)&stack_addr; + if (current > stack_addr) { + if ((current - stack_addr) < min_size) + return FALSE; + } else { + if (current - (stack_addr - stack_size) < min_size) + return FALSE; + } + return TRUE; +} + static MonoObject * ves_icall_System_Object_MemberwiseClone (MonoObject *this) { @@ -1312,19 +1321,27 @@ type_from_name (const char *str, MonoBoolean ignoreCase) * Dec 10, 2005 - Martin. */ - if (dest) + if (dest) { assembly = dest->klass->image->assembly; - else { + type_resolve = TRUE; + } else { g_warning (G_STRLOC); } } - if (assembly) + if (assembly) { + /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */ type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve); - + } + if (!info.assembly.name && !type) /* try mscorlib */ type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve); + if (assembly && !type && type_resolve) { + type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */ + type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve); + } + mono_reflection_free_type_info (&info); g_free (temp_str); @@ -1375,11 +1392,9 @@ static MonoReflectionType* ves_icall_type_from_handle (MonoType *handle) { MonoDomain *domain = mono_domain_get (); - MonoClass *klass = mono_class_from_mono_type (handle); MONO_ARCH_SAVE_REGS; - mono_class_init (klass); return mono_type_get_object (domain, handle); } @@ -1517,12 +1532,42 @@ ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, M klass = mono_class_from_mono_type (type->type); klassc = mono_class_from_mono_type (c->type); + /* Interface check requires a more complex setup so we + * only do for them. Otherwise we simply avoid mono_class_init. + */ + if (check_interfaces) { + mono_class_init_or_throw (klass); + mono_class_init_or_throw (klassc); + } else if (!klass->supertypes || !klassc->supertypes) { + mono_loader_lock (); + mono_class_setup_supertypes (klass); + mono_class_setup_supertypes (klassc); + mono_loader_unlock (); + } + if (type->type->byref) return klassc == mono_defaults.object_class; return mono_class_is_subclass_of (klass, klassc, check_interfaces); } +static gboolean +mono_type_is_primitive (MonoType *type) +{ + return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) || + type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U; +} + +static MonoType* +mono_type_get_underlying_type_ignore_byref (MonoType *type) +{ + if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) + return mono_class_enum_basetype (type->data.klass); + if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype) + return mono_class_enum_basetype (type->data.generic_class->container_class); + return type; +} + static guint32 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c) { @@ -1539,9 +1584,34 @@ ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType klass = mono_class_from_mono_type (type->type); klassc = mono_class_from_mono_type (c->type); - if (type->type->byref && !c->type->byref) + mono_class_init_or_throw (klass); + mono_class_init_or_throw (klassc); + + if (type->type->byref ^ c->type->byref) return FALSE; + if (type->type->byref) { + MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type); + MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type); + + klass = mono_class_from_mono_type (t); + klassc = mono_class_from_mono_type (ot); + + if (mono_type_is_primitive (t)) { + return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size; + } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) { + return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num; + } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) { + return t->type == ot->type; + } else { + if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR) + return FALSE; + + if (klass->valuetype) + return klass == klassc; + return klass->valuetype == klassc->valuetype; + } + } return mono_class_is_assignable_from (klass, klassc); } @@ -1549,6 +1619,7 @@ static guint32 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj) { MonoClass *klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); return mono_object_isinst (obj, klass) != NULL; } @@ -1556,9 +1627,6 @@ static guint32 ves_icall_get_attributes (MonoReflectionType *type) { MonoClass *klass = mono_class_from_mono_type (type->type); - - MONO_ARCH_SAVE_REGS; - return klass->flags; } @@ -1588,27 +1656,33 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField * } static MonoReflectionField* -ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass) +ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type) { + gboolean found = FALSE; + MonoClass *klass; + MonoClass *k; + g_assert (handle); - if (!klass) + if (!type) { klass = handle->parent; + } else { + klass = mono_class_from_mono_type (type); - /* FIXME: check that handle is a field of klass or of a parent: return null - * and throw the exception in managed code. - */ - return mono_field_get_object (mono_domain_get (), klass, handle); -} - -static MonoReflectionField* -ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle) -{ - MONO_ARCH_SAVE_REGS; + /* Check that the field belongs to the class */ + for (k = klass; k; k = k->parent) { + if (k == handle->parent) { + found = TRUE; + break; + } + } - g_assert (handle); + if (!found) + /* The managed code will throw the exception */ + return NULL; + } - return mono_field_get_object (mono_domain_get (), handle->parent, handle); + return mono_field_get_object (mono_domain_get (), klass, handle); } static MonoArray* @@ -1697,129 +1771,18 @@ ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean decla static MonoObject * ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj) { - MonoObject *o; + MonoClass *fklass = field->klass; MonoClassField *cf = field->field; - MonoClass *klass; - MonoVTable *vtable; - MonoType *t; - MonoDomain *domain = mono_object_domain (field); - gchar *v; - gboolean is_static = FALSE; - gboolean is_ref = FALSE; - - MONO_ARCH_SAVE_REGS; + MonoDomain *domain = mono_object_domain (field); - if (field->klass->image->assembly->ref_only) + if (fklass->image->assembly->ref_only) mono_raise_exception (mono_get_exception_invalid_operation ( "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods.")); - + if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) mono_security_core_clr_ensure_reflection_access_field (cf); - mono_class_init (field->klass); - - if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) - is_static = TRUE; - - if (obj && !is_static) { - /* Check that the field belongs to the object */ - gboolean found = FALSE; - MonoClass *k; - - for (k = obj->vtable->klass; k; k = k->parent) { - if (k == cf->parent) { - found = TRUE; - break; - } - } - - if (!found) { - char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf), cf->parent->name, obj->vtable->klass->name); - MonoException *ex = mono_get_exception_argument (NULL, msg); - g_free (msg); - mono_raise_exception (ex); - } - } - - t = mono_type_get_underlying_type (cf->type); - switch (t->type) { - case MONO_TYPE_STRING: - case MONO_TYPE_OBJECT: - case MONO_TYPE_CLASS: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - is_ref = TRUE; - break; - case MONO_TYPE_U1: - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_U2: - case MONO_TYPE_I2: - case MONO_TYPE_CHAR: - case MONO_TYPE_U: - case MONO_TYPE_I: - case MONO_TYPE_U4: - case MONO_TYPE_I4: - case MONO_TYPE_R4: - case MONO_TYPE_U8: - case MONO_TYPE_I8: - case MONO_TYPE_R8: - case MONO_TYPE_VALUETYPE: - is_ref = t->byref; - break; - case MONO_TYPE_GENERICINST: - if (mono_type_generic_inst_is_valuetype (t)) { - is_ref = t->byref; - } else { - is_ref = TRUE; - } - break; - default: - g_error ("type 0x%x not handled in " - "ves_icall_Monofield_GetValue", t->type); - return NULL; - } - - vtable = NULL; - if (is_static) { - vtable = mono_class_vtable (domain, cf->parent); - if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL)) - mono_runtime_class_init (vtable); - } - - if (is_ref) { - if (is_static) { - mono_field_static_get_value (vtable, cf, &o); - } else { - mono_field_get_value (obj, cf, &o); - } - return o; - } - - if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) { - MonoClass *nklass = mono_class_from_mono_type (cf->type); - guint8 *buf; - - /* Convert the Nullable structure into a boxed vtype */ - if (is_static) - buf = (guint8*)vtable->data + cf->offset; - else - buf = (guint8*)obj + cf->offset; - - return mono_nullable_box (buf, nklass); - } - - /* boxed value type */ - klass = mono_class_from_mono_type (cf->type); - o = mono_object_new (domain, klass); - v = ((gchar *) o) + sizeof (MonoObject); - if (is_static) { - mono_field_static_get_value (vtable, cf, v); - } else { - mono_field_get_value (obj, cf, v); - } - - return o; + return mono_field_get_value_object (domain, cf, obj); } static void @@ -1897,7 +1860,7 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob } if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) { - MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent); + MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE); if (!vtable->initialized) mono_runtime_class_init (vtable); mono_field_static_set_value (vtable, cf, v); @@ -1931,6 +1894,7 @@ ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this) def_value = mono_class_get_field_default_value (field, &def_type); + /*FIXME unify this with reflection.c:mono_get_object_from_blob*/ switch (def_type) { case MONO_TYPE_U1: case MONO_TYPE_I1: @@ -2034,6 +1998,7 @@ ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info) MONO_STRUCT_SETREF (info, remove_method, event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL); MONO_STRUCT_SETREF (info, raise_method, event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL); +#ifndef MONO_SMALL_CONFIG if (event->event->other) { int i, n = 0; while (event->event->other [n]) @@ -2043,72 +2008,109 @@ ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info) for (i = 0; i < n; i++) mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL)); } +#endif +} + +static void +collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error) +{ + int i; + MonoClass *ic; + + mono_class_setup_interfaces (klass, error); + if (!mono_error_ok (error)) + return; + + for (i = 0; i < klass->interface_count; i++) { + ic = klass->interfaces [i]; + g_hash_table_insert (ifaces, ic, ic); + + collect_interfaces (ic, ifaces, error); + if (!mono_error_ok (error)) + return; + } +} + +typedef struct { + MonoArray *iface_array; + MonoGenericContext *context; + MonoError *error; + MonoDomain *domain; + int next_idx; +} FillIfaceArrayData; + +static void +fill_iface_array (gpointer key, gpointer value, gpointer user_data) +{ + FillIfaceArrayData *data = user_data; + MonoClass *ic = key; + MonoType *ret = &ic->byval_arg, *inflated = NULL; + + if (!mono_error_ok (data->error)) + return; + + if (data->context && ic->generic_class && ic->generic_class->context.class_inst->is_open) { + inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error); + if (!mono_error_ok (data->error)) + return; + } + + mono_array_setref (data->iface_array, data->next_idx++, mono_type_get_object (data->domain, ret)); + + if (inflated) + mono_metadata_free_type (inflated); } static MonoArray* ves_icall_Type_GetInterfaces (MonoReflectionType* type) { - MonoDomain *domain = mono_object_domain (type); - MonoArray *intf; - GPtrArray *ifaces = NULL; - int i; + MonoError error; MonoClass *class = mono_class_from_mono_type (type->type); MonoClass *parent; - MonoBitSet *slots; - MonoGenericContext *context = NULL; + FillIfaceArrayData data = { 0 }; + int len; - MONO_ARCH_SAVE_REGS; + GHashTable *iface_hash = g_hash_table_new (NULL, NULL); if (class->generic_class && class->generic_class->context.class_inst->is_open) { - context = mono_class_get_context (class); + data.context = mono_class_get_context (class); class = class->generic_class->container_class; } - mono_class_setup_vtable (class); - - slots = mono_bitset_new (class->max_interface_id + 1, 0); - for (parent = class; parent; parent = parent->parent) { - GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent); - if (tmp_ifaces) { - for (i = 0; i < tmp_ifaces->len; ++i) { - MonoClass *ic = g_ptr_array_index (tmp_ifaces, i); + mono_class_setup_interfaces (parent, &error); + if (!mono_error_ok (&error)) + goto fail; + collect_interfaces (parent, iface_hash, &error); + if (!mono_error_ok (&error)) + goto fail; + } - if (mono_bitset_test (slots, ic->interface_id)) - continue; + data.error = &error; + data.domain = mono_object_domain (type); - mono_bitset_set (slots, ic->interface_id); - if (ifaces == NULL) - ifaces = g_ptr_array_new (); - g_ptr_array_add (ifaces, ic); - } - g_ptr_array_free (tmp_ifaces, TRUE); - } - } - mono_bitset_free (slots); + len = g_hash_table_size (iface_hash); + if (len == 0) + return mono_array_new_cached (data.domain, mono_defaults.monotype_class, 0); - if (!ifaces) - return mono_array_new_cached (domain, mono_defaults.monotype_class, 0); - - intf = mono_array_new_cached (domain, mono_defaults.monotype_class, ifaces->len); - for (i = 0; i < ifaces->len; ++i) { - MonoClass *ic = g_ptr_array_index (ifaces, i); - MonoType *ret = &ic->byval_arg, *inflated = NULL; - if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open) - inflated = ret = mono_class_inflate_generic_type (ret, context); - - mono_array_setref (intf, i, mono_type_get_object (domain, ret)); - if (inflated) - mono_metadata_free_type (inflated); - } - g_ptr_array_free (ifaces, TRUE); + data.iface_array = mono_array_new_cached (data.domain, mono_defaults.monotype_class, len); + g_hash_table_foreach (iface_hash, fill_iface_array, &data); + if (!mono_error_ok (&error)) + goto fail; - return intf; + g_hash_table_destroy (iface_hash); + return data.iface_array; + +fail: + g_hash_table_destroy (iface_hash); + mono_error_raise_exception (&error); + return NULL; } static void ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods) { + gboolean variance_used; MonoClass *class = mono_class_from_mono_type (type->type); MonoClass *iclass = mono_class_from_mono_type (iface->type); MonoReflectionMethod *member; @@ -2118,20 +2120,20 @@ ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType MonoDomain *domain; MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (class); + mono_class_init_or_throw (iclass); mono_class_setup_vtable (class); - /* type doesn't implement iface: the exception is thrown in managed code */ - if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id)) - return; + ioffset = mono_class_interface_offset_with_variance (class, iclass, &variance_used); + if (ioffset == -1) + return; len = mono_class_num_methods (iclass); - ioffset = mono_class_interface_offset (class, iclass); domain = mono_object_domain (type); mono_gc_wbarrier_generic_store (targets, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len)); mono_gc_wbarrier_generic_store (methods, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len)); iter = NULL; - iter = NULL; while ((method = mono_class_get_methods (iclass, &iter))) { member = mono_method_get_object (domain, method, iclass); mono_array_setref (*methods, i, member); @@ -2146,6 +2148,7 @@ static void ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size) { MonoClass *klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); if (klass->image->dynamic) { MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type; @@ -2167,6 +2170,7 @@ ves_icall_MonoType_GetElementType (MonoReflectionType *type) return mono_type_get_object (mono_object_domain (type), &type->type->data.klass->byval_arg); class = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (class); // GetElementType should only return a type for: // Array Pointer PassedByRef @@ -2184,9 +2188,6 @@ static MonoReflectionType* ves_icall_get_type_parent (MonoReflectionType *type) { MonoClass *class = mono_class_from_mono_type (type->type); - - MONO_ARCH_SAVE_REGS; - return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL; } @@ -2218,7 +2219,7 @@ static MonoBoolean ves_icall_type_iscomobject (MonoReflectionType *type) { MonoClass *klass = mono_class_from_mono_type (type->type); - MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (klass); return (klass && klass->is_com_object); } @@ -2227,8 +2228,7 @@ static MonoReflectionModule* ves_icall_MonoType_get_Module (MonoReflectionType *type) { MonoClass *class = mono_class_from_mono_type (type->type); - - MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (class); return mono_module_get_object (mono_object_domain (type), class->image); } @@ -2239,7 +2239,7 @@ ves_icall_MonoType_get_Assembly (MonoReflectionType *type) MonoDomain *domain = mono_domain_get (); MonoClass *class = mono_class_from_mono_type (type->type); - MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (class); return mono_assembly_get_object (domain, class->image->assembly); } @@ -2264,30 +2264,12 @@ ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type) return class ? mono_type_get_object (domain, &class->byval_arg) : NULL; } -static MonoReflectionType* -ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type) -{ - MonoDomain *domain = mono_domain_get (); - MonoClass *class = mono_class_from_mono_type (type->type); - - MONO_ARCH_SAVE_REGS; - - if (class->enumtype && mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */ - return mono_type_get_object (domain, mono_class_enum_basetype (class)); - else if (class->element_class) - return mono_type_get_object (domain, &class->element_class->byval_arg); - else - return NULL; -} - static MonoString* ves_icall_MonoType_get_Name (MonoReflectionType *type) { MonoDomain *domain = mono_domain_get (); MonoClass *class = mono_class_from_mono_type (type->type); - MONO_ARCH_SAVE_REGS; - if (type->type->byref) { char *n = g_strdup_printf ("%s&", class->name); MonoString *res = mono_string_new (domain, n); @@ -2306,8 +2288,6 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type) MonoDomain *domain = mono_domain_get (); MonoClass *class = mono_class_from_mono_type (type->type); - MONO_ARCH_SAVE_REGS; - while (class->nested_in) class = class->nested_in; @@ -2320,9 +2300,13 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type) static gint32 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type) { - MonoClass *class = mono_class_from_mono_type (type->type); + MonoClass *class; - MONO_ARCH_SAVE_REGS; + if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) + mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type")); + + class = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (class); return class->rank; } @@ -2333,11 +2317,12 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type) MonoArray *res; MonoClass *klass, *pklass; MonoDomain *domain = mono_object_domain (type); - MonoVTable *array_vtable = mono_class_vtable (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1)); + MonoVTable *array_vtable = mono_class_vtable_full (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1), TRUE); int i; MONO_ARCH_SAVE_REGS; klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); if (klass->generic_container) { MonoGenericContainer *container = klass->generic_container; @@ -2370,7 +2355,6 @@ ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type) return FALSE; klass = mono_class_from_mono_type (type->type); - return klass->generic_container != NULL; } @@ -2384,14 +2368,19 @@ ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type) return NULL; klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + if (klass->generic_container) { return type; /* check this one */ } if (klass->generic_class) { MonoClass *generic_class = klass->generic_class->container_class; + gpointer tb; - if (generic_class->wastypebuilder && generic_class->reflection_info) - return generic_class->reflection_info; + tb = mono_class_get_ref_info (generic_class); + + if (generic_class->wastypebuilder && tb) + return tb; else return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg); } @@ -2404,7 +2393,8 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array) MonoType *geninst, **types; int i, count; - MONO_ARCH_SAVE_REGS; + g_assert (IS_MONOTYPE (type)); + mono_class_init_or_throw (mono_class_from_mono_type (type->type)); count = mono_array_length (type_array); types = g_new0 (MonoType *, count); @@ -2417,489 +2407,154 @@ ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array) geninst = mono_reflection_bind_generic_parameters (type, count, types); g_free (types); if (!geninst) - return NULL; - - return mono_type_get_object (mono_object_domain (type), geninst); -} - -static gboolean -ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type) -{ - MonoClass *klass; - MONO_ARCH_SAVE_REGS; - - if (type->type->byref) - return FALSE; - - klass = mono_class_from_mono_type (type->type); - return klass->generic_class != NULL; -} - -static gboolean -ves_icall_Type_get_IsGenericType (MonoReflectionType *type) -{ - MonoClass *klass; - MONO_ARCH_SAVE_REGS; - - if (!IS_MONOTYPE (type)) - return FALSE; - - if (type->type->byref) - return FALSE; - - klass = mono_class_from_mono_type (type->type); - return klass->generic_class != NULL || klass->generic_container != NULL; -} - -static gint32 -ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type) -{ - MONO_ARCH_SAVE_REGS; - - if (!IS_MONOTYPE (type)) - return -1; - - if (is_generic_parameter (type->type)) - return mono_type_get_generic_param_num (type->type); - return -1; -} - -static GenericParameterAttributes -ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type) -{ - MONO_ARCH_SAVE_REGS; - - g_assert (IS_MONOTYPE (type)); - g_assert (is_generic_parameter (type->type)); - return mono_generic_param_info (type->type->data.generic_param)->flags; -} - -static MonoArray * -ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type) -{ - MonoGenericParamInfo *param_info; - MonoDomain *domain; - MonoClass **ptr; - MonoArray *res; - int i, count; - - MONO_ARCH_SAVE_REGS; - - g_assert (IS_MONOTYPE (type)); - - domain = mono_object_domain (type); - param_info = mono_generic_param_info (type->type->data.generic_param); - for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++) - ; - - res = mono_array_new (domain, mono_defaults.monotype_class, count); - for (i = 0; i < count; i++) - mono_array_setref (res, i, mono_type_get_object (domain, ¶m_info->constraints [i]->byval_arg)); - - - return res; -} - -static MonoBoolean -ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type) -{ - MONO_ARCH_SAVE_REGS; - return is_generic_parameter (type->type); -} - -static MonoBoolean -ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb) -{ - MONO_ARCH_SAVE_REGS; - return is_generic_parameter (tb->type.type); -} - -static void -ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype, - MonoReflectionType *t) -{ - enumtype->type = t->type; -} - -static MonoReflectionType* -ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type) -{ - MonoDynamicGenericClass *gclass; - MonoReflectionType *parent = NULL, *res; - MonoDomain *domain; - MonoType *inflated; - MonoClass *klass; - - - MONO_ARCH_SAVE_REGS; - - g_assert (type->type.type->data.generic_class->is_dynamic); - gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class; - - domain = mono_object_domain (type); - klass = mono_class_from_mono_type (type->generic_type->type.type); - - if (!klass->generic_class && !klass->generic_container) - return NULL; - - parent = monotype_cast (type->generic_type->parent); - - if (!parent || (parent->type->type != MONO_TYPE_GENERICINST)) - return NULL; - - inflated = mono_class_inflate_generic_type ( - parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass)); - - res = mono_type_get_object (domain, inflated); - mono_metadata_free_type (inflated); - return res; -} - -static MonoArray* -ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type) -{ - static MonoClass *System_Reflection_MonoGenericClass; - MonoGenericClass *gclass; - MonoReflectionTypeBuilder *tb = NULL; - MonoClass *klass = NULL; - MonoDomain *domain; - MonoArray *res; - int icount, i; - - MONO_ARCH_SAVE_REGS; - - if (!System_Reflection_MonoGenericClass) { - System_Reflection_MonoGenericClass = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "MonoGenericClass"); - g_assert (System_Reflection_MonoGenericClass); - } - - domain = mono_object_domain (type); - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - - tb = type->generic_type; - icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; - - res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount); - - for (i = 0; i < icount; i++) { - MonoReflectionType *iface; - MonoType *it; - - if (tb) { - iface = mono_array_get (tb->interfaces, MonoReflectionType *, i); - it = iface->type; - } else - it = &klass->interfaces [i]->byval_arg; - - it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass)); - - iface = mono_type_get_object (domain, it); - mono_array_setref (res, i, iface); - mono_metadata_free_type (it); - } - - return res; -} - -static MonoReflectionMethod* -ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type, - MonoReflectionMethod* generic) -{ - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - int i; - - MONO_ARCH_SAVE_REGS; - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - - dgclass = (MonoDynamicGenericClass *) gclass; - - domain = mono_object_domain (type); - - for (i = 0; i < dgclass->count_methods; i++) - if (generic->method->token == dgclass->methods [i]->token) - return mono_method_get_object (domain, dgclass->methods [i], NULL); - - return NULL; -} - -static MonoReflectionMethod* -ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type, - MonoReflectionMethod* generic) -{ - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - int i; - - MONO_ARCH_SAVE_REGS; - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - - dgclass = (MonoDynamicGenericClass *) gclass; - - domain = mono_object_domain (type); - - for (i = 0; i < dgclass->count_ctors; i++) - if (generic->method->token == dgclass->ctors [i]->token) - return mono_method_get_object (domain, dgclass->ctors [i], NULL); - - return NULL; -} - - -static MonoReflectionField* -ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type, - MonoString* generic_name) -{ - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - MonoClass *refclass; - char *utf8_name = mono_string_to_utf8 (generic_name); - int i; - - MONO_ARCH_SAVE_REGS; - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - - dgclass = (MonoDynamicGenericClass *) gclass; - - refclass = mono_class_from_mono_type (type->type.type); - - domain = mono_object_domain (type); - - for (i = 0; i < dgclass->count_fields; i++) - if (strcmp (utf8_name, mono_field_get_name (&dgclass->fields [i])) == 0) { - g_free (utf8_name); - return mono_field_get_object (domain, refclass, &dgclass->fields [i]); - } - - g_free (utf8_name); - - return NULL; -} - - -static MonoReflectionMethod* -ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, - MonoReflectionMethod* generic) -{ - MonoDomain *domain; - MonoClass *klass; - MonoMethod *method; - gpointer iter; - - MONO_ARCH_SAVE_REGS; - - domain = ((MonoObject *)type)->vtable->domain; - - klass = mono_class_from_mono_type (type->type); - - iter = NULL; - while ((method = mono_class_get_methods (klass, &iter))) { - if (method->token == generic->method->token) - return mono_method_get_object (domain, method, klass); - } - - return NULL; -} - -static MonoArray* -ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type, - MonoReflectionType *reflected_type) -{ - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - MonoClass *refclass; - MonoArray *res; - int i; - - MONO_ARCH_SAVE_REGS; - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - dgclass = (MonoDynamicGenericClass *) gclass; - - refclass = mono_class_from_mono_type (reflected_type->type); - - domain = mono_object_domain (type); - res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods); - - for (i = 0; i < dgclass->count_methods; i++) - mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass)); + return NULL; - return res; + return mono_type_get_object (mono_object_domain (type), geninst); } -static MonoArray* -ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type, - MonoReflectionType *reflected_type) +static gboolean +ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type) { - static MonoClass *System_Reflection_ConstructorInfo; - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - MonoClass *refclass; - MonoArray *res; - int i; - + MonoClass *klass; MONO_ARCH_SAVE_REGS; - if (!System_Reflection_ConstructorInfo) - System_Reflection_ConstructorInfo = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "ConstructorInfo"); + if (type->type->byref) + return FALSE; - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - dgclass = (MonoDynamicGenericClass *) gclass; + klass = mono_class_from_mono_type (type->type); - refclass = mono_class_from_mono_type (reflected_type->type); + return klass->generic_class != NULL; +} - domain = mono_object_domain (type); - res = mono_array_new_cached (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors); +static gboolean +ves_icall_Type_get_IsGenericType (MonoReflectionType *type) +{ + MonoClass *klass; + MONO_ARCH_SAVE_REGS; + + if (!IS_MONOTYPE (type)) + return FALSE; - for (i = 0; i < dgclass->count_ctors; i++) - mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass)); + if (type->type->byref) + return FALSE; - return res; + klass = mono_class_from_mono_type (type->type); + return klass->generic_class != NULL || klass->generic_container != NULL; } -static MonoArray* -ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type, - MonoReflectionType *reflected_type) +static gint32 +ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type) { - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - MonoClass *refclass; - MonoArray *res; - int i; - MONO_ARCH_SAVE_REGS; - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - dgclass = (MonoDynamicGenericClass *) gclass; - - refclass = mono_class_from_mono_type (reflected_type->type); + if (!IS_MONOTYPE (type)) + return -1; - domain = mono_object_domain (type); - res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields); + if (is_generic_parameter (type->type)) + return mono_type_get_generic_param_num (type->type); + return -1; +} - for (i = 0; i < dgclass->count_fields; i++) - mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i])); +static GenericParameterAttributes +ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type) +{ + MONO_ARCH_SAVE_REGS; - return res; + g_assert (IS_MONOTYPE (type)); + g_assert (is_generic_parameter (type->type)); + return mono_generic_param_info (type->type->data.generic_param)->flags; } -static MonoArray* -ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type, - MonoReflectionType *reflected_type) +static MonoArray * +ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type) { - static MonoClass *System_Reflection_PropertyInfo; - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; + MonoGenericParamInfo *param_info; MonoDomain *domain; - MonoClass *refclass; + MonoClass **ptr; MonoArray *res; - int i; + int i, count; MONO_ARCH_SAVE_REGS; - if (!System_Reflection_PropertyInfo) - System_Reflection_PropertyInfo = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "PropertyInfo"); - - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - dgclass = (MonoDynamicGenericClass *) gclass; - - refclass = mono_class_from_mono_type (reflected_type->type); + g_assert (IS_MONOTYPE (type)); domain = mono_object_domain (type); - res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties); + param_info = mono_generic_param_info (type->type->data.generic_param); + for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++) + ; + + res = mono_array_new (domain, mono_defaults.monotype_class, count); + for (i = 0; i < count; i++) + mono_array_setref (res, i, mono_type_get_object (domain, ¶m_info->constraints [i]->byval_arg)); - for (i = 0; i < dgclass->count_properties; i++) - mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i])); return res; } -static MonoArray* -ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type, - MonoReflectionType *reflected_type) +static MonoBoolean +ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type) { - static MonoClass *System_Reflection_EventInfo; - MonoGenericClass *gclass; - MonoDynamicGenericClass *dgclass; - MonoDomain *domain; - MonoClass *refclass; - MonoArray *res; - int i; + MONO_ARCH_SAVE_REGS; + return is_generic_parameter (type->type); +} +static MonoBoolean +ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb) +{ MONO_ARCH_SAVE_REGS; + return is_generic_parameter (tb->type.type); +} - if (!System_Reflection_EventInfo) - System_Reflection_EventInfo = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "EventInfo"); +static void +ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype, + MonoReflectionType *t) +{ + enumtype->type = t->type; +} - gclass = type->type.type->data.generic_class; - g_assert (gclass->is_dynamic); - dgclass = (MonoDynamicGenericClass *) gclass; +static MonoReflectionMethod* +ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, + MonoReflectionMethod* generic) +{ + MonoDomain *domain; + MonoClass *klass; + MonoMethod *method; + gpointer iter; + + MONO_ARCH_SAVE_REGS; - refclass = mono_class_from_mono_type (reflected_type->type); + domain = ((MonoObject *)type)->vtable->domain; - domain = mono_object_domain (type); - res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events); + klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); - for (i = 0; i < dgclass->count_events; i++) - mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i])); + iter = NULL; + while ((method = mono_class_get_methods (klass, &iter))) { + if (method->token == generic->method->token) + return mono_method_get_object (domain, method, klass); + } - return res; + return NULL; } -static MonoReflectionType* -ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type, - MonoReflectionType *target) -{ - MonoType *res_type; - MonoClass *gklass; - MonoReflectionType *res; - - MONO_ARCH_SAVE_REGS; - gklass = mono_class_from_mono_type (type->type.type); - res_type = mono_class_inflate_generic_type (mono_reflection_type_get_handle (target), mono_class_get_context (gklass)); - res = mono_type_get_object (mono_object_domain (type), res_type); - mono_metadata_free_type (res_type); - return res; -} static MonoReflectionMethod * -ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type) +ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *ref_type) { MonoMethod *method; - MonoClass *klass; + MonoType *type = ref_type->type; MONO_ARCH_SAVE_REGS; - if (type->type->byref || type->type->type != MONO_TYPE_MVAR) + if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) + mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments")); + if (type->type == MONO_TYPE_VAR) return NULL; - method = mono_type_get_generic_param_owner (type->type)->owner.method; + method = mono_type_get_generic_param_owner (type)->owner.method; g_assert (method); - klass = mono_class_from_mono_type (type->type); - return mono_method_get_object (mono_object_domain (type), method, klass); + return mono_method_get_object (mono_object_domain (ref_type), method, method->klass); } static MonoReflectionDllImportAttribute* @@ -2919,7 +2574,7 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method) const char *scope = NULL; guint32 flags; - if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) + if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) return NULL; if (!DllImportAttributeClass) { @@ -2937,6 +2592,11 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method) import = method_aux->dllentry; scope = method_aux->dll; } + + if (!import || !scope) { + mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information")); + return NULL; + } } else { if (piinfo->implmap_idx) { @@ -3006,7 +2666,9 @@ ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method) if (imethod->context.class_inst) { MonoClass *klass = ((MonoMethod *) imethod)->klass; - result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass)); + /*Generic methods gets the context of the GTD.*/ + if (mono_class_get_context (klass)) + result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass)); } return mono_method_get_object (mono_object_domain (method), result, NULL); @@ -3087,6 +2749,11 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr mono_security_core_clr_ensure_reflection_access_method (m); if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) { + if (!mono_class_vtable_full (mono_object_domain (method), m->klass, FALSE)) { + mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass)); + return NULL; + } + if (this) { if (!mono_object_isinst (this, m->klass)) { mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.")); @@ -3120,12 +2787,13 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr if (m->klass->rank && !strcmp (m->name, ".ctor")) { int i; - mono_array_size_t *lengths; - mono_array_size_t *lower_bounds; + uintptr_t *lengths; + intptr_t *lower_bounds; pcount = mono_array_length (params); - lengths = alloca (sizeof (mono_array_size_t) * pcount); + lengths = alloca (sizeof (uintptr_t) * pcount); + /* Note: the synthetized array .ctors have int32 as argument type */ for (i = 0; i < pcount; ++i) - lengths [i] = *(mono_array_size_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject)); + lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject)); if (m->klass->rank == pcount) { /* Only lengths provided. */ @@ -3133,7 +2801,7 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr } else { g_assert (pcount == (m->klass->rank * 2)); /* lower bounds are first. */ - lower_bounds = lengths; + lower_bounds = (intptr_t*)lengths; lengths += m->klass->rank; } @@ -3219,11 +2887,8 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA if (field_klass->valuetype) { size = mono_type_size (field->type, &align); -#ifdef HAVE_SGEN_GC + g_assert (size == mono_class_value_size (field_klass, NULL)); mono_gc_wbarrier_value_copy ((char *)this + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass); -#endif - memcpy ((char *)this + field->offset, - ((char *)val) + sizeof (MonoObject), size); } else { mono_gc_wbarrier_set_field (this, (char*)this + field->offset, val); } @@ -3339,6 +3004,7 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value) MonoDomain *domain; MonoClass *enumc, *objc; MonoObject *res; + MonoType *etype; guint64 val; MONO_ARCH_SAVE_REGS; @@ -3348,6 +3014,9 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value) domain = mono_object_domain (enumType); enumc = mono_class_from_mono_type (enumType->type); + + mono_class_init_or_throw (enumc); + objc = value->vtable->klass; if (!enumc->enumtype) @@ -3355,9 +3024,14 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value) if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8))) 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.")); + etype = mono_class_enum_basetype (enumc); + if (!etype) + /* MS throws this for typebuilders */ + mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType")); + res = mono_object_new (domain, enumc); val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type); - write_enum_value ((char *)res + sizeof (MonoObject), mono_class_enum_basetype (enumc)->type, val); + write_enum_value ((char *)res + sizeof (MonoObject), etype->type, val); return res; } @@ -3392,9 +3066,20 @@ ves_icall_System_Enum_get_value (MonoObject *this) static MonoReflectionType * ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type) { + MonoType *etype; + MonoClass *klass; + MONO_ARCH_SAVE_REGS; - return mono_type_get_object (mono_object_domain (type), mono_class_enum_basetype (mono_class_from_mono_type (type->type))); + klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + + etype = mono_class_enum_basetype (klass); + if (!etype) + /* MS throws this for typebuilders */ + mono_raise_exception (mono_get_exception_argument ("Type must be a type provided by the runtime.", "enumType")); + + return mono_type_get_object (mono_object_domain (type), etype); } static int @@ -3491,6 +3176,8 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info) MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (enumc); + MONO_STRUCT_SETREF (info, utype, mono_type_get_object (domain, mono_class_enum_basetype (enumc))); nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0; MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues)); @@ -3567,15 +3254,14 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl int (*compare_func) (const char *s1, const char *s2) = NULL; domain = ((MonoObject *)type)->vtable->domain; klass = startklass = mono_class_from_mono_type (type->type); - - MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (klass); if (!name) mono_raise_exception (mono_get_exception_argument_null ("name")); if (type->type->byref) return NULL; - compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp; + compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp; handle_parent: if (klass->exception_type != MONO_EXCEPTION_NONE) @@ -3648,6 +3334,9 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon klass = startklass = mono_class_from_mono_type (type->type); refklass = mono_class_from_mono_type (reftype->type); + mono_class_init_or_throw (klass); + mono_class_init_or_throw (refklass); + mono_ptr_array_init (tmp_array, 2); handle_parent: @@ -3725,13 +3414,12 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui int i, len, match, nslots; /*FIXME, use MonoBitSet*/ guint32 method_slots_default [8]; - guint32 *method_slots; + guint32 *method_slots = NULL; gchar *mname = NULL; int (*compare_func) (const char *s1, const char *s2) = NULL; MonoVTable *array_vtable; + MonoException *ex; MonoPtrArray tmp_array; - - MONO_ARCH_SAVE_REGS; mono_ptr_array_init (tmp_array, 4); @@ -3742,23 +3430,29 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui } domain = ((MonoObject *)type)->vtable->domain; - array_vtable = mono_class_vtable (domain, MethodInfo_array); + array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE); if (type->type->byref) return mono_array_new_specific (array_vtable, 0); klass = startklass = mono_class_from_mono_type (type->type); refklass = mono_class_from_mono_type (reftype->type); + + mono_class_init_or_throw (klass); + mono_class_init_or_throw (refklass); + len = 0; if (name != NULL) { mname = mono_string_to_utf8 (name); - compare_func = (ignore_case) ? g_strcasecmp : strcmp; + compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp; } /* An optimization for calls made from Delegate:CreateDelegate () */ if (klass->delegate && mname && !strcmp (mname, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) { method = mono_get_delegate_invoke (klass); + if (mono_loader_get_last_error ()) + goto loader_error; member = (MonoObject*)mono_method_get_object (domain, method, refklass); - + res = mono_array_new_specific (array_vtable, 1); mono_array_setref (res, 0, member); g_free (mname); @@ -3766,11 +3460,13 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui } mono_class_setup_vtable (klass); + if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ()) + goto loader_error; if (is_generic_parameter (type->type)) - nslots = klass->parent->vtable_size; + nslots = mono_class_get_vtable_size (klass->parent); else - nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size; + nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass); if (nslots >= sizeof (method_slots_default) * 8) { method_slots = g_new0 (guint32, nslots / 32 + 1); } else { @@ -3779,8 +3475,8 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui } handle_parent: mono_class_setup_vtable (klass); - if (klass->exception_type != MONO_EXCEPTION_NONE) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ()) + goto loader_error; iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { @@ -3789,7 +3485,8 @@ handle_parent: g_assert (method->slot < nslots); if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f))) continue; - method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f); + if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT)) + method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f); } if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)) @@ -3840,6 +3537,20 @@ handle_parent: mono_ptr_array_destroy (tmp_array); return res; + +loader_error: + g_free (mname); + if (method_slots != method_slots_default) + g_free (method_slots); + mono_ptr_array_destroy (tmp_array); + if (klass->exception_type != MONO_EXCEPTION_NONE) { + ex = mono_class_get_exception_for_failure (klass); + } else { + ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ()); + mono_loader_clear_error (); + } + mono_raise_exception (ex); + return NULL; } static MonoArray* @@ -3865,6 +3576,9 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag klass = startklass = mono_class_from_mono_type (type->type); refklass = mono_class_from_mono_type (reftype->type); + mono_class_init_or_throw (klass); + mono_class_init_or_throw (refklass); + if (klass->exception_type != MONO_EXCEPTION_NONE) mono_raise_exception (mono_class_get_exception_for_failure (klass)); @@ -3973,9 +3687,13 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, if (type->type->byref) return mono_array_new_cached (domain, System_Reflection_PropertyInfo, 0); klass = startklass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + + + if (name != NULL) { propname = mono_string_to_utf8 (name); - compare_func = (ignore_case) ? g_strcasecmp : strcmp; + compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp; } mono_class_setup_vtable (klass); @@ -4062,6 +3780,7 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 MonoEvent *event; MonoMethod *method; gchar *event_name; + int (*compare_func) (const char *s1, const char *s2); MONO_ARCH_SAVE_REGS; @@ -4071,13 +3790,16 @@ ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 klass = startklass = mono_class_from_mono_type (type->type); domain = mono_object_domain (type); + mono_class_init_or_throw (klass); + + compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp; handle_parent: if (klass->exception_type != MONO_EXCEPTION_NONE) mono_raise_exception (mono_class_get_exception_for_failure (klass)); iter = NULL; while ((event = mono_class_get_events (klass, &iter))) { - if (strcmp (event->name, event_name)) + if (compare_func (event->name, event_name)) continue; method = event->add; @@ -4146,6 +3868,8 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon if (type->type->byref) return mono_array_new_cached (domain, System_Reflection_EventInfo, 0); klass = startklass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + handle_parent: if (klass->exception_type != MONO_EXCEPTION_NONE) @@ -4222,6 +3946,8 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3 if (type->type->byref) return NULL; klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + str = mono_string_to_utf8 (name); handle_parent: @@ -4281,8 +4007,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags) if (type->type->byref) return mono_array_new (domain, mono_defaults.monotype_class, 0); klass = mono_class_from_mono_type (type->type); - if (klass->exception_type != MONO_EXCEPTION_NONE) - mono_raise_exception (mono_class_get_exception_for_failure (klass)); + mono_class_init_or_throw (klass); /* * If a nested type is generic, return its generic type definition. @@ -4483,7 +4208,7 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse replace_shadow_path (domain, dirname, &absolute); g_free (dirname); -#if PLATFORM_WIN32 +#if HOST_WIN32 { gint i; for (i = strlen (absolute) - 1; i >= 0; i--) @@ -4495,7 +4220,7 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse uri = g_filename_to_uri (absolute, NULL, NULL); } else { const char *prepend = "file://"; -#if PLATFORM_WIN32 +#if HOST_WIN32 if (*absolute == '/' && *(absolute + 1) == '/') { prepend = "file:"; } else { @@ -5004,7 +4729,8 @@ ves_icall_GetCurrentMethod (void) { MonoMethod *m = mono_method_get_last_managed (); - MONO_ARCH_SAVE_REGS; + while (m->is_inflated) + m = ((MonoMethodInflated*)m)->declaring; return mono_method_get_object (mono_domain_get (), m, NULL); } @@ -5028,6 +4754,8 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass) } mono_class_setup_methods (method->klass); + if (method->klass->exception_type) + return NULL; for (i = 0; i < method->klass->method.count; ++i) { if (method->klass->methods [i] == method) { offset = i; @@ -5035,6 +4763,8 @@ mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass) } } mono_class_setup_methods (klass); + if (klass->exception_type) + return NULL; g_assert (offset >= 0 && offset < klass->method.count); return klass->methods [offset]; } @@ -5047,8 +4777,11 @@ ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMeth klass = mono_class_from_mono_type (type); if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass)) return NULL; - if (method->klass != klass) + if (method->klass != klass) { method = mono_method_get_equivalent_method (method, klass); + if (!method) + return NULL; + } } else klass = method->klass; return mono_method_get_object (mono_domain_get (), method, klass); @@ -5117,7 +4850,6 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full MonoString *res; gchar *name; - MONO_ARCH_SAVE_REGS; if (full_name) format = assembly_qualified ? MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED : @@ -5140,6 +4872,14 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full return res; } +static int +vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType *this) +{ + MonoClass *klass = mono_class_from_mono_type (this->type); + mono_class_init_or_throw (klass); + return mono_security_core_clr_class_level (klass); +} + static void fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token) { @@ -5171,7 +4911,7 @@ fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *a codebase = g_strdup (absolute); -#if PLATFORM_WIN32 +#if HOST_WIN32 { gint i; for (i = strlen (codebase) - 1; i >= 0; i--) @@ -5271,14 +5011,14 @@ ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, if (g_path_is_absolute (mass->image->name)) { fill_reflection_assembly_name (mono_object_domain (assembly), aname, &mass->aname, mass->image->name, TRUE, - TRUE, mono_framework_version () >= 2); + TRUE, TRUE); return; } absolute = g_build_filename (mass->basedir, mass->image->name, NULL); fill_reflection_assembly_name (mono_object_domain (assembly), aname, &mass->aname, absolute, TRUE, TRUE, - mono_framework_version () >= 2); + TRUE); g_free (absolute); } @@ -5322,8 +5062,7 @@ ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, } fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, - TRUE, mono_framework_version () == 1, - mono_framework_version () >= 2); + TRUE, FALSE, TRUE); g_free (filename); mono_image_close (image); @@ -5582,7 +5321,7 @@ ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module static gpointer ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module) { -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 if (module->image && module->image->is_module_handle) return module->image->raw_data; #endif @@ -5973,6 +5712,20 @@ ves_icall_Type_IsArrayImpl (MonoReflectionType *t) return res; } +static void +check_for_invalid_type (MonoClass *klass) +{ + char *name; + MonoString *str; + if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF) + return; + + name = mono_type_get_full_name (klass); + str = mono_string_new (mono_domain_get (), name); + g_free (name); + mono_raise_exception ((MonoException*)mono_get_exception_type_load (str, NULL)); + +} static MonoReflectionType * ves_icall_Type_make_array_type (MonoReflectionType *type, int rank) { @@ -5981,6 +5734,9 @@ ves_icall_Type_make_array_type (MonoReflectionType *type, int rank) MONO_ARCH_SAVE_REGS; klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + check_for_invalid_type (klass); + if (rank == 0) //single dimentional array aklass = mono_array_class_get (klass, 1); else @@ -5997,6 +5753,8 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type) MONO_ARCH_SAVE_REGS; klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + check_for_invalid_type (klass); return mono_type_get_object (mono_object_domain (type), &klass->this_arg); } @@ -6004,9 +5762,11 @@ ves_icall_Type_make_byref_type (MonoReflectionType *type) static MonoReflectionType * ves_icall_Type_MakePointerType (MonoReflectionType *type) { - MonoClass *pklass; + MonoClass *klass, *pklass; - MONO_ARCH_SAVE_REGS; + klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); + check_for_invalid_type (klass); pklass = mono_ptr_class_get (type->type); @@ -6024,6 +5784,8 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (delegate_class); + mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class); if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) { @@ -6064,7 +5826,7 @@ ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this) */ #define FILETIME_ADJUST ((guint64)504911232000000000LL) -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */ static void convert_to_absolute_date(SYSTEMTIME *date) @@ -6094,7 +5856,7 @@ convert_to_absolute_date(SYSTEMTIME *date) } #endif -#ifndef PLATFORM_WIN32 +#ifndef HOST_WIN32 /* * Return's the offset from GMT of a local time. * @@ -6134,7 +5896,7 @@ gmt_offset(struct tm *tm, time_t t) static guint32 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names) { -#ifndef PLATFORM_WIN32 +#ifndef HOST_WIN32 MonoDomain *domain = mono_domain_get (); struct tm start, tt; time_t t; @@ -6438,7 +6200,7 @@ ves_icall_System_Environment_get_UserName (void) static MonoString * ves_icall_System_Environment_get_MachineName (void) { -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) gunichar2 *buf; guint32 len; MonoString *result; @@ -6470,14 +6232,11 @@ ves_icall_System_Environment_get_MachineName (void) static int ves_icall_System_Environment_get_Platform (void) { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) /* Win32NT */ return 2; #elif defined(__MACH__) /* OSX */ - if (mono_framework_version () < 2) - return 128; - // // For compatibility with our client code, this will be 4 for a while. // We will eventually move to 6 to match .NET, but it requires all client @@ -6487,8 +6246,6 @@ ves_icall_System_Environment_get_Platform (void) return 4; #else /* Unix */ - if (mono_framework_version () < 2) - return 128; return 4; #endif } @@ -6498,7 +6255,7 @@ ves_icall_System_Environment_get_NewLine (void) { MONO_ARCH_SAVE_REGS; -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) return mono_string_new (mono_domain_get (), "\r\n"); #else return mono_string_new (mono_domain_get (), "\n"); @@ -6537,7 +6294,7 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name) * arm-apple-darwin9. We'll manually define the symbol on Apple as it does * in fact exist on all implementations (so far) */ -gchar ***_NSGetEnviron(); +gchar ***_NSGetEnviron(void); #define environ (*_NSGetEnviron()) #else extern @@ -6549,7 +6306,7 @@ char **environ; static MonoArray * ves_icall_System_Environment_GetEnvironmentVariableNames (void) { -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 MonoArray *names; MonoDomain *domain; MonoString *str; @@ -6641,7 +6398,9 @@ ves_icall_System_Environment_GetEnvironmentVariableNames (void) static void ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value) { -#ifdef PLATFORM_WIN32 + MonoError error; +#ifdef HOST_WIN32 + gunichar2 *utf16_name, *utf16_value; #else gchar *utf8_name, *utf8_value; @@ -6649,7 +6408,7 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M MONO_ARCH_SAVE_REGS; -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 utf16_name = mono_string_to_utf16 (name); if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) { SetEnvironmentVariable (utf16_name, NULL); @@ -6672,7 +6431,11 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M return; } - utf8_value = mono_string_to_utf8 (value); + utf8_value = mono_string_to_utf8_checked (value, &error); + if (!mono_error_ok (&error)) { + g_free (utf8_name); + mono_error_raise_exception (&error); + } g_setenv (utf8_name, utf8_value, TRUE); g_free (utf8_name); @@ -6689,6 +6452,9 @@ ves_icall_System_Environment_Exit (int result) mono_runtime_set_shutting_down (); + /* This will kill the tp threads which cannot be suspended */ + mono_thread_pool_cleanup (); + /* Suspend all managed threads since the runtime is going away */ mono_thread_suspend_all_other_threads (); @@ -6707,7 +6473,7 @@ ves_icall_System_Environment_GetGacPath (void) static MonoString* ves_icall_System_Environment_GetWindowsFolderPath (int folder) { -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif @@ -6880,7 +6646,7 @@ ves_icall_System_Environment_get_HasShutdownStarted (void) static void ves_icall_System_Environment_BroadcastSettingChange (void) { -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, NULL, L"Environment", SMTO_ABORTIFHUNG, 2000, 0); #endif } @@ -6923,6 +6689,7 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod ( method = rmethod->method; klass = mono_class_from_mono_type (rtype->type); + mono_class_init_or_throw (klass); if (MONO_CLASS_IS_INTERFACE (klass)) return NULL; @@ -6941,7 +6708,9 @@ ves_icall_Remoting_RemotingServices_GetVirtualMethod ( vtable = klass->vtable; if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { - int offs = mono_class_interface_offset (klass, method->klass); + gboolean variance_used = FALSE; + /*MS fails with variant interfaces but it's the right thing to do anyway.*/ + int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used); if (offs >= 0) res = vtable [offs + method->slot]; } else { @@ -6967,7 +6736,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (Mo MONO_ARCH_SAVE_REGS; klass = mono_class_from_mono_type (type->type); - vtable = mono_class_vtable (mono_domain_get (), klass); + vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE); if (enable) vtable->remote = 1; else vtable->remote = 0; @@ -6983,13 +6752,14 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas domain = mono_object_domain (type); klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); if (klass->rank >= 1) { g_assert (klass->rank == 1); return (MonoObject *) mono_array_new (domain, klass->element_class, 0); } else { /* Bypass remoting object creation check */ - return mono_object_new_alloc_specific (mono_class_vtable (domain, klass)); + return mono_object_new_alloc_specific (mono_class_vtable_full (domain, klass, TRUE)); } } @@ -7059,7 +6829,7 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void) path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL); -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) /* Avoid mixing '/' and '\\' */ { gint i; @@ -7099,7 +6869,7 @@ ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void) path = g_path_get_dirname (mono_get_config_dir ()); -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) /* Avoid mixing '/' and '\\' */ { gint i; @@ -7145,16 +6915,16 @@ ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, static MonoBoolean ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void) { - return mono_debug_using_mono_debugger (); + return mono_debug_using_mono_debugger () || mono_is_debugger_attached (); } static void ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message) { -#if defined (PLATFORM_WIN32) +#if defined (HOST_WIN32) OutputDebugString (mono_string_chars (message)); #else - g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n"); + g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n"); #endif } @@ -7169,6 +6939,7 @@ ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type) domain = mono_object_domain (type); klass = mono_class_from_mono_type (type->type); + mono_class_init_or_throw (klass); if (mono_class_is_nullable (klass)) /* No arguments -> null */ @@ -7178,7 +6949,7 @@ ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type) } static MonoReflectionMethod * -ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m) +ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition) { MonoClass *klass, *parent; MonoMethod *method = m->method; @@ -7198,13 +6969,19 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m) if (klass->generic_class) klass = klass->generic_class->container_class; - /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */ - for (parent = klass->parent; parent != NULL; parent = parent->parent) { - mono_class_setup_vtable (parent); - if (parent->vtable_size <= method->slot) - break; - klass = parent; - } + if (definition) { + /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */ + for (parent = klass->parent; parent != NULL; parent = parent->parent) { + mono_class_setup_vtable (parent); + if (parent->vtable_size <= method->slot) + break; + klass = parent; + } + } else { + klass = klass->parent; + if (!klass) + return m; + } if (klass == method->klass) return m; @@ -7249,16 +7026,6 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start) iter->args = start; } else { iter->args = argsp + sizeof (gpointer); -#ifndef MONO_ARCH_REGPARMS - { - guint32 i, arg_size; - gint32 align; - for (i = 0; i < iter->sig->sentinelpos; ++i) { - arg_size = mono_type_stack_size (iter->sig->params [i], &align); - iter->args = (char*)iter->args + arg_size; - } - } -#endif } iter->num_args = iter->sig->param_count - iter->sig->sentinelpos; @@ -7397,6 +7164,8 @@ ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType gpointer iter = NULL; MONO_ARCH_SAVE_REGS; + mono_class_init_or_throw (klass); + while ((m = mono_class_get_methods (klass, &iter))) prelink_method (m); } @@ -7474,10 +7243,32 @@ static MonoArray* param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional) { MonoType *type = param->ClassImpl->type; - MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl; - MonoImage *image = method->method->klass->image; - int pos = param->PositionImpl; - MonoMethodSignature *sig = mono_method_signature (method->method); + MonoClass *member_class = mono_object_class (param->MemberImpl); + MonoMethod *method = NULL; + MonoImage *image; + int pos; + MonoMethodSignature *sig; + + if (mono_class_is_reflection_method_or_constructor (member_class)) { + MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl; + method = rmethod->method; + } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) { + MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl; + if (!(method = prop->property->get)) + method = prop->property->set; + g_assert (method); + } else { + char *type_name = mono_type_get_full_name (member_class); + char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name); + MonoException *ex = mono_get_exception_not_supported (msg); + g_free (type_name); + g_free (msg); + mono_raise_exception (ex); + } + + image = method->klass->image; + pos = param->PositionImpl; + sig = mono_method_signature (method); if (pos == -1) type = sig->ret; else @@ -7511,16 +7302,67 @@ property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean return type_array_from_modifiers (image, type, optional); } +/* + *Construct a MonoType suited to be used to decode a constant blob object. + * + * @type is the target type which will be constructed + * @blob_type is the blob type, for example, that comes from the constant table + * @real_type is the expected constructed type. + */ +static void +mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type) +{ + type->type = blob_type; + type->data.klass = NULL; + if (blob_type == MONO_TYPE_CLASS) + type->data.klass = mono_defaults.object_class; + else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) { + /* For enums, we need to use the base type */ + type->type = MONO_TYPE_VALUETYPE; + type->data.klass = mono_class_from_mono_type (real_type); + } else + type->data.klass = mono_class_from_mono_type (real_type); +} + +static MonoObject* +property_info_get_default_value (MonoReflectionProperty *property) +{ + MonoType blob_type; + MonoProperty *prop = property->property; + MonoType *type = get_property_type (prop); + MonoDomain *domain = mono_object_domain (property); + MonoTypeEnum def_type; + const char *def_value; + MonoObject *o; + + g_assert (!prop->parent->image->dynamic); + + mono_class_init (prop->parent); + + if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) + mono_raise_exception (mono_get_exception_invalid_operation (NULL)); + + def_value = mono_class_get_property_default_value (prop, &def_type); + + mono_type_from_blob_type (&blob_type, def_type, type); + o = mono_get_object_from_blob (domain, &blob_type, def_value); + + return o; +} + static MonoBoolean custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type) { + MonoClass *attr_class = mono_class_from_mono_type (attr_type->type); MonoCustomAttrInfo *cinfo; gboolean found; + mono_class_init_or_throw (attr_class); + cinfo = mono_reflection_get_custom_attrs_info (obj); if (!cinfo) return FALSE; - found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type)); + found = mono_custom_attrs_has_attr (cinfo, attr_class); if (!cinfo->cached) mono_custom_attrs_free (cinfo); return found; @@ -7529,7 +7371,13 @@ custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type) static MonoArray* custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type) { - MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL); + MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL; + MonoArray *res; + + if (attr_class) + mono_class_init_or_throw (attr_class); + + res = mono_reflection_get_custom_attrs_by_type (obj, attr_class); if (mono_loader_get_last_error ()) { mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ())); @@ -7541,17 +7389,15 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type) } } -static MonoBoolean -GCHandle_CheckCurrentDomain (guint32 gchandle) -{ - return mono_gchandle_is_in_domain (gchandle, mono_domain_get ()); -} - static MonoString* ves_icall_Mono_Runtime_GetDisplayName (void) { - static const char display_name_str [] = "Mono " VERSION; - MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str); + char *info; + MonoString *display_name; + + info = mono_get_runtime_callbacks ()->get_runtime_build_info (); + display_name = mono_string_new (mono_domain_get (), info); + g_free (info); return display_name; } @@ -8125,7 +7971,7 @@ mono_create_icall_signature (const char *sigstr) res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1); res->pinvoke = 1; -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 /* * Under windows, the default pinvoke calling convention is STDCALL but * we need CDECL.