Merge pull request #5636 from BrzVlad/fix-xmm-scan
[mono.git] / mono / mini / jit-icalls.c
index 56c7bc8169f76b54e7f1f01caa0e23471a01a259..fa3d7a4681971e74fafa19d297ab476de42c470d 100644 (file)
@@ -1328,12 +1328,15 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
 {
        MonoMethod *m;
        int vt_slot, iface_offset;
+       gboolean is_iface = FALSE;
 
        error_init (error);
 
        if (mono_class_is_interface (klass)) {
                MonoObject *this_obj;
 
+               is_iface = TRUE;
+
                /* Have to use the receiver's type instead of klass, the receiver is a ref type */
                this_obj = *(MonoObject**)mp;
                g_assert (this_obj);
@@ -1359,21 +1362,33 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
                        m = mono_class_inflate_generic_method (m, mono_method_get_context (cmethod));
        }
 
-       if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class))
+       if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class)) {
                /*
                 * Calling a non-vtype method with a vtype receiver, has to box.
                 */
                *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
-       else if (klass->valuetype)
-               /*
-                * Calling a vtype method with a vtype receiver
-                */
-               *this_arg = mp;
-       else
+       } else if (klass->valuetype) {
+               if (is_iface) {
+                       /*
+                        * The original type is an interface, so the receiver is a ref,
+                          the called method is a vtype method, need to unbox.
+                       */
+                       MonoObject *this_obj = *(MonoObject**)mp;
+
+                       *this_arg = mono_object_unbox (this_obj);
+               } else {
+                       /*
+                        * Calling a vtype method with a vtype receiver
+                        */
+                       *this_arg = mp;
+               }
+       } else {
                /*
                 * Calling a non-vtype method
                 */
                *this_arg = *(gpointer*)mp;
+       }
+
        return m;
 }