[jit] Add support for constrained calls with vtype return types in gsharedvt code...
authorZoltan Varga <vargaz@gmail.com>
Thu, 14 Aug 2014 19:54:08 +0000 (15:54 -0400)
committerZoltan Varga <vargaz@gmail.com>
Thu, 14 Aug 2014 19:54:55 +0000 (15:54 -0400)
mono/mini/gshared.cs
mono/mini/method-to-ir.c

index 342dec7060a2f2f36a7c38929570398ac1f21b6e..27149e9085d7a5ee63311e6cac1789caaba04991 100644 (file)
@@ -1018,7 +1018,36 @@ public class Tests
                return 0;
        }
 
-       struct Pair<T1, T2> {
+       interface IConstrainedCalls {
+               Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
+       }
+
+       public interface IReturnVType {
+               Pair<int, int> return_vtype ();
+       }
+
+       public class CConstrainedCalls : IConstrainedCalls {
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
+                       return t.return_vtype ();
+               }
+       }
+
+       class ReturnVType : IReturnVType {
+               public Pair<int, int> return_vtype () {
+                       return new Pair<int, int> () { First = 1, Second = 2 };
+               }
+       }
+
+       public static int test_0_constrained_vtype_ret () {
+               IConstrainedCalls c = new CConstrainedCalls ();
+               var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
+               if (r.First != 1 || r.Second != 2)
+                       return 1;
+               return 0;
+       }
+
+       public struct Pair<T1, T2> {
                public T1 First;
                public T2 Second;
        }
index a9a4eb19228234f94b419d2df549ae5f7c292006..618069dc58b38e0457f93862eefb0e9395fcaae2 100644 (file)
@@ -8025,7 +8025,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        } else if (cmethod->klass->image != mono_defaults.corlib && !(cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) && !cmethod->klass->valuetype) {
                                                /* 'The type parameter is instantiated as a reference type' case below. */
                                        } else if (((cmethod->klass == mono_defaults.object_class) || (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) || (!cmethod->klass->valuetype && cmethod->klass->image != mono_defaults.corlib)) &&
-                                                          (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || mini_is_gsharedvt_type (cfg, fsig->ret)) &&
+                                                          (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mini_is_gsharedvt_type (cfg, fsig->ret)) &&
                                                           (fsig->param_count == 0 || (!fsig->hasthis && fsig->param_count == 1) || (fsig->param_count == 1 && (MONO_TYPE_IS_REFERENCE (fsig->params [0]) || mini_is_gsharedvt_type (cfg, fsig->params [0]))))) {
                                                MonoInst *args [16];
 
@@ -8074,7 +8074,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                                if (mini_is_gsharedvt_type (cfg, fsig->ret)) {
                                                        ins = handle_unbox_gsharedvt (cfg, mono_class_from_mono_type (fsig->ret), ins, &bblock);
-                                               } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret)) {
+                                               } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret)) {
                                                        MonoInst *add;
 
                                                        /* Unbox */