[interpreter] properly inflate method on generic virtual call
authorBernhard Urban <bernhard.urban@xamarin.com>
Mon, 27 Feb 2017 16:55:53 +0000 (17:55 +0100)
committerBernhard Urban <bernhard.urban@xamarin.com>
Tue, 28 Feb 2017 21:59:28 +0000 (22:59 +0100)
mono/mini/interpreter/interp.c
mono/mini/objects.cs

index b0d5c379cb8fe0809facdb56b4fee3419a425451..b3cc2297693c9b916bdbad4611b323923eb3b973 100644 (file)
@@ -314,7 +314,20 @@ get_virtual_method (MonoDomain *domain, RuntimeMethod *runtime_method, MonoObjec
                /* TODO: interface offset lookup is slow, go through IMT instead */
                slot += mono_class_interface_offset (obj->vtable->klass, m->klass);
        }
+
        MonoMethod *virtual_method = obj->vtable->klass->vtable [slot];
+       if (m->is_inflated && mono_method_get_context (m)->method_inst) {
+               MonoGenericContext context = { NULL, NULL };
+
+               if (mono_class_is_ginst (virtual_method->klass))
+                       context.class_inst = mono_class_get_generic_class (virtual_method->klass)->context.class_inst;
+               else if (mono_class_is_gtd (virtual_method->klass))
+                       context.class_inst = mono_class_get_generic_container (virtual_method->klass)->context.class_inst;
+               context.method_inst = mono_method_get_context (m)->method_inst;
+
+               virtual_method = mono_class_inflate_generic_method_checked (virtual_method, &context, &error);
+               mono_error_cleanup (&error); /* FIXME: don't swallow the error */
+       }
        RuntimeMethod *virtual_runtime_method = mono_interp_get_runtime_method (domain, virtual_method, &error);
        mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        return virtual_runtime_method;
index 005e276fbb18d565934733bc3d15e54b24c5fff2..cf45fb89d1992f0287ec032004c7e586f12f7e73 100644 (file)
@@ -1768,7 +1768,6 @@ ncells ) {
                }
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_delegate_to_virtual_generic_on_ifaces () {
                IComparer2 c = new AClass ();