From 59bd14c23317b5be2caa54df44ee10131ff03f33 Mon Sep 17 00:00:00 2001 From: kumpera Date: Fri, 9 Apr 2010 01:06:50 +0000 Subject: [PATCH] 2010-04-08 Rodrigo Kumpera * icall.c (ves_icall_MonoField_GetValueInternal): This function is a near identical copy of mono_field_get_value_object. So simply call it. * object.c (mono_field_get_value_object): Handle literal fields on open generic classes. Fixes #594942. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mono@155111 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- mono/metadata/ChangeLog | 11 +++++ mono/metadata/icall.c | 121 ++---------------------------------------------- mono/metadata/object.c | 35 +++++++++----- 3 files changed, 40 insertions(+), 127 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 48d4599ae..ef1cc37af 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,5 +1,16 @@ 2010-04-08 Rodrigo Kumpera + * icall.c (ves_icall_MonoField_GetValueInternal): This function + is a near identical copy of mono_field_get_value_object. So simply + call it. + + * object.c (mono_field_get_value_object): Handle literal fields + on open generic classes. + + Fixes #594942. + +2010-04-08 Rodrigo Kumpera + * reflection.c (mono_reflection_create_runtime_class): Setup parent/supertype information again since it can be changed without notice. diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index e5237a8f8..819beaa02 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1749,129 +1749,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; + MonoDomain *domain = mono_object_domain (field); - MONO_ARCH_SAVE_REGS; - - 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_full (domain, cf->parent, TRUE); - 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 diff --git a/mono/metadata/object.c b/mono/metadata/object.c index ccbf4c5af..59a62636e 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -2974,6 +2974,7 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje gchar *v; gboolean is_static = FALSE; gboolean is_ref = FALSE; + gboolean is_literal = FALSE; switch (field->type->type) { case MONO_TYPE_STRING: @@ -3001,7 +3002,7 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje is_ref = field->type->byref; break; case MONO_TYPE_GENERICINST: - is_ref = !field->type->data.generic_class->container_class->valuetype; + is_ref = !mono_type_generic_inst_is_valuetype (field->type); break; default: g_error ("type 0x%x not handled in " @@ -3009,21 +3010,30 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje return NULL; } + if (field->type->attrs & FIELD_ATTRIBUTE_LITERAL) + is_literal = TRUE; + if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) { is_static = TRUE; - vtable = mono_class_vtable (domain, field->parent); - if (!vtable) { - char *name = mono_type_get_full_name (field->parent); - g_warning ("Could not retrieve the vtable for type %s in mono_field_get_value_object", name); - g_free (name); - return NULL; + + if (!is_literal) { + vtable = mono_class_vtable (domain, field->parent); + if (!vtable) { + char *name = mono_type_get_full_name (field->parent); + /*FIXME extend this to use the MonoError api*/ + g_warning ("Could not retrieve the vtable for type %s in mono_field_get_value_object", name); + g_free (name); + return NULL; + } + if (!vtable->initialized) + mono_runtime_class_init (vtable); } - if (!vtable->initialized) - mono_runtime_class_init (vtable); } if (is_ref) { - if (is_static) { + if (is_literal) { + get_default_field_value (domain, field, &o); + } else if (is_static) { mono_field_static_get_value (vtable, field, &o); } else { mono_field_get_value (obj, field, &o); @@ -3039,7 +3049,10 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje o = mono_object_new (domain, klass); v = ((gchar *) o) + sizeof (MonoObject); - if (is_static) { + + if (is_literal) { + get_default_field_value (domain, field, v); + } else if (is_static) { mono_field_static_get_value (vtable, field, v); } else { mono_field_get_value (obj, field, v); -- 2.11.4.GIT