From f2c50b06d5529de7c7e177d2c84ef3090946fb1d Mon Sep 17 00:00:00 2001 From: kumpera Date: Tue, 9 Feb 2010 12:41:41 +0000 Subject: [PATCH] 2010-02-09 Rodrigo Kumpera * icall.c (param_info_get_type_modifiers): Handle the case when the member object is a property. This happens which instances returned by PropertyInfo::GetIndexParameters (). * reflection.c (mono_reflection_get_custom_attrs_info): Ditto. * object-internals.h: Export mono_class_is_reflection_method_or_constructor as part of the internal API. Fixes #574434. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mono@151093 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- mono/metadata/ChangeLog | 12 ++++++++++ mono/metadata/icall.c | 30 ++++++++++++++++++++---- mono/metadata/object-internals.h | 3 +++ mono/metadata/reflection.c | 50 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 592bdbbd0..3e233ee87 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,15 @@ +2010-02-09 Rodrigo Kumpera + + * icall.c (param_info_get_type_modifiers): Handle the case when the member object is a + property. This happens which instances returned by PropertyInfo::GetIndexParameters (). + + * reflection.c (mono_reflection_get_custom_attrs_info): Ditto. + + * object-internals.h: Export mono_class_is_reflection_method_or_constructor as part of + the internal API. + + Fixes #574434. + 2010-02-09 Mark Probst * threads.c: Removed two assertions that were too strict. Added a diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 5be1a9591..117b1d35f 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -7205,10 +7205,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 diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index 0ac39dd7d..090781e0c 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -1454,6 +1454,9 @@ mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, char * mono_string_to_utf8_checked (MonoString *s, MonoError *error) MONO_INTERNAL; +gboolean +mono_class_is_reflection_method_or_constructor (MonoClass *class) MONO_INTERNAL; + #endif /* __MONO_OBJECT_INTERNALS_H__ */ diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index c66aea9de..e33a2466b 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -190,7 +190,10 @@ static gboolean is_sre_ctor_builder (MonoClass *class); static gboolean is_sre_field_builder (MonoClass *class); static gboolean is_sr_mono_method (MonoClass *class); static gboolean is_sr_mono_cmethod (MonoClass *class); +static gboolean is_sr_mono_generic_method (MonoClass *class); +static gboolean is_sr_mono_generic_cmethod (MonoClass *class); static gboolean is_sr_mono_field (MonoClass *class); +static gboolean is_sr_mono_property (MonoClass *class); static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method); static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m); @@ -7624,6 +7627,8 @@ mono_reflection_get_token (MonoObject *obj) token = mono_class_get_event_token (p->event); } else if (strcmp (klass->name, "ParameterInfo") == 0) { MonoReflectionParameter *p = (MonoReflectionParameter*)obj; + MonoClass *member_class = mono_object_class (p->MemberImpl); + g_assert (mono_class_is_reflection_method_or_constructor (member_class)); token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl); } else if (strcmp (klass->name, "Module") == 0) { @@ -8637,8 +8642,26 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj) cinfo = mono_custom_attrs_from_method (rmethod->method); } else if (strcmp ("ParameterInfo", klass->name) == 0) { MonoReflectionParameter *param = (MonoReflectionParameter*)obj; - MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl; - cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1); + MonoClass *member_class = mono_object_class (param->MemberImpl); + if (mono_class_is_reflection_method_or_constructor (member_class)) { + MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl; + cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1); + } else if (is_sr_mono_property (member_class)) { + MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl; + MonoMethod *method; + if (!(method = prop->property->get)) + method = prop->property->set; + g_assert (method); + + cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1); + } else { + char *type_name = mono_type_get_full_name (member_class); + char *msg = g_strdup_printf ("Custom attributes 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); + } } else if (strcmp ("AssemblyBuilder", klass->name) == 0) { MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj; cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs); @@ -8830,11 +8853,34 @@ is_sr_mono_cmethod (MonoClass *class) } static gboolean +is_sr_mono_generic_method (MonoClass *class) +{ + check_corlib_type_cached (class, "System.Reflection", "MonoGenericMethod"); +} + +static gboolean +is_sr_mono_generic_cmethod (MonoClass *class) +{ + check_corlib_type_cached (class, "System.Reflection", "MonoGenericCMethod"); +} + +static gboolean is_sr_mono_field (MonoClass *class) { check_corlib_type_cached (class, "System.Reflection", "MonoField"); } +static gboolean +is_sr_mono_property (MonoClass *class) +{ + check_corlib_type_cached (class, "System.Reflection", "MonoProperty"); +} + +gboolean +mono_class_is_reflection_method_or_constructor (MonoClass *class) +{ + return is_sr_mono_method (class) || is_sr_mono_cmethod (class) || is_sr_mono_generic_method (class) || is_sr_mono_generic_cmethod (class); +} MonoType* mono_reflection_type_get_handle (MonoReflectionType* ref) -- 2.11.4.GIT