Author: raja Date: 2008-02-20 03:21:00 -0500 (Wed, 20 Feb 2008) New Revision: 96224
Modified: trunk/mono/mono/metadata/ChangeLog trunk/mono/mono/metadata/class-internals.h trunk/mono/mono/metadata/class.c trunk/mono/mono/metadata/metadata.c trunk/mono/mono/metadata/reflection.c Log: 2008-02-20 Rodrigo Kumpera <[EMAIL PROTECTED]> Raja R Harinath <[EMAIL PROTECTED]> Fix #354757 * class-internals.h (struct _MonoMethodInflated.is_mb_open): Add. * class.c (mono_class_inflate_generic_method_full): Initialize it when a fully-open method is instantiated. * metadata.c (inflated_method_equal, inflated_method_hash): Update to new field. * reflection.c (inflate_mono_method): Don't create a temporary context. Modified: trunk/mono/mono/metadata/ChangeLog =================================================================== --- trunk/mono/mono/metadata/ChangeLog 2008-02-20 07:56:54 UTC (rev 96223) +++ trunk/mono/mono/metadata/ChangeLog 2008-02-20 08:21:00 UTC (rev 96224) @@ -1,3 +1,14 @@ +2008-02-20 Rodrigo Kumpera <[EMAIL PROTECTED]> + Raja R Harinath <[EMAIL PROTECTED]> + + Fix #354757 + * class-internals.h (struct _MonoMethodInflated.is_mb_open): Add. + * class.c (mono_class_inflate_generic_method_full): Initialize it + when a fully-open method is instantiated. + * metadata.c (inflated_method_equal, inflated_method_hash): Update + to new field. + * reflection.c (inflate_mono_method): Don't create a temporary context. + 2008-02-20 Raja R Harinath <[EMAIL PROTECTED]> * icall.c (ves_icall_MonoMethod_GetGenericMethodDefinition): Modified: trunk/mono/mono/metadata/class-internals.h =================================================================== --- trunk/mono/mono/metadata/class-internals.h 2008-02-20 07:56:54 UTC (rev 96223) +++ trunk/mono/mono/metadata/class-internals.h 2008-02-20 08:21:00 UTC (rev 96224) @@ -415,6 +415,9 @@ MonoMethod *declaring; /* the generic method definition. */ MonoGenericContext context; /* The current instantiation */ gpointer reflection_info; + + /* TODO we MUST get rid of this field, it's an ugly hack nobody is proud of. */ + guint is_mb_open : 1; /* This is the fully open instantiation of a generic method_builder. Worse than is_tb_open, but it's temporary */ }; /* Modified: trunk/mono/mono/metadata/class.c =================================================================== --- trunk/mono/mono/metadata/class.c 2008-02-20 07:56:54 UTC (rev 96223) +++ trunk/mono/mono/metadata/class.c 2008-02-20 08:21:00 UTC (rev 96224) @@ -633,6 +633,7 @@ MonoMethodInflated *iresult, *cached; MonoMethodSignature *sig; MonoGenericContext tmp_context; + gboolean is_mb_open = FALSE; /* The `method' has already been instantiated before => we need to peel out the instantiation and create a new context */ while (method->is_inflated) { @@ -651,10 +652,22 @@ if (!method->generic_container && !method->klass->generic_container) return method; + /* + * The reason for this hack is to fix the behavior of inflating generic methods that come from a MethodBuilder. + * What happens is that instantiating a generic MethodBuilder with its own arguments should create a diferent object. + * This is opposite to the way non-SRE MethodInfos behave. + * + * FIXME: express this better, somehow! + */ + is_mb_open = method->generic_container && + method->klass->image->dynamic && !method->klass->wastypebuilder && + context->method_inst == method->generic_container->context.method_inst; + mono_stats.inflated_method_count++; iresult = g_new0 (MonoMethodInflated, 1); iresult->context = *context; iresult->declaring = method; + iresult->is_mb_open = is_mb_open; if (!context->method_inst && method->generic_container) iresult->context.method_inst = method->generic_container->context.method_inst; Modified: trunk/mono/mono/metadata/metadata.c =================================================================== --- trunk/mono/mono/metadata/metadata.c 2008-02-20 07:56:54 UTC (rev 96223) +++ trunk/mono/mono/metadata/metadata.c 2008-02-20 08:21:00 UTC (rev 96224) @@ -1960,6 +1960,8 @@ const MonoMethodInflated *mb = b; if (ma->declaring != mb->declaring) return FALSE; + if (ma->is_mb_open != mb->is_mb_open) + return FALSE; return mono_metadata_generic_context_equal (&ma->context, &mb->context); } @@ -1967,7 +1969,7 @@ inflated_method_hash (gconstpointer a) { const MonoMethodInflated *ma = a; - return mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring); + return mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring) + ma->is_mb_open; } static gboolean Modified: trunk/mono/mono/metadata/reflection.c =================================================================== --- trunk/mono/mono/metadata/reflection.c 2008-02-20 07:56:54 UTC (rev 96223) +++ trunk/mono/mono/metadata/reflection.c 2008-02-20 08:21:00 UTC (rev 96224) @@ -9007,7 +9007,6 @@ inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj) { MonoMethodInflated *imethod; - MonoGenericContext tmp_context; MonoGenericContext *context; MonoClass *klass; @@ -9015,14 +9014,6 @@ g_assert (klass->generic_class); context = mono_class_get_context (klass); - if (method->generic_container) { - g_assert (method->klass == klass->generic_class->container_class); - - tmp_context.class_inst = klass->generic_class->context.class_inst; - tmp_context.method_inst = method->generic_container->context.method_inst; - context = &tmp_context; - } - imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context); if (method->generic_container) { MOVING_GC_REGISTER (&imethod->reflection_info); _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches