2010-03-23 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Tue, 23 Mar 2010 18:22:04 +0000 (18:22 -0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 23 Mar 2010 18:22:04 +0000 (18:22 -0000)
* mini-generic-sharing.c (get_shared_class): Handle partially shared methods
in non-shared classes correctly.
(generic_inst_is_sharable): Allow all primitive types in partial sharing.
Turn on partial sharing.

svn path=/trunk/mono/; revision=154072

mono/mini/ChangeLog
mono/mini/generics.cs
mono/mini/mini-generic-sharing.c

index 38da0e63e9c151491826c38d2b16ea92e1be3517..2c099e96fe784aa36427ea5bfb7cc389a00c5465 100755 (executable)
@@ -1,3 +1,10 @@
+2010-03-23  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-generic-sharing.c (get_shared_class): Handle partially shared methods
+       in non-shared classes correctly.
+       (generic_inst_is_sharable): Allow all primitive types in partial sharing.
+       Turn on partial sharing.
+
 2010-03-23  Zoltan Varga  <vargaz@gmail.com>
 
        * mini-amd64.h: Put back MONO_ARCH_NOMAP32BIT for OpenBSD which was removed
index c2502a784942c886efec75364247406e0a0e19ee..a75e3ad59a8f5c5a21a2c5a0b29374f3787d9914 100644 (file)
@@ -584,6 +584,11 @@ class Tests {
                return messages.Max(i => i.MessageID);
        }
 
+       public static int test_0_partial_shared_method_in_nonshared_class () {
+               var c = new Class1<double> ();
+               return (c.Foo<string> (5).GetType () == typeof (Class1<string>)) ? 0 : 1;
+       }
+
        class Message {
                public int MessageID {
                        get; set;
@@ -602,6 +607,10 @@ class Tests {
                public virtual void Do (Class2<T> t) {
                        t.Foo ();
                }
+
+               public virtual object Foo<U> (T t) {
+                       return new Class1<U> ();
+               }
        }
 
        public interface IFace1<T> {
index 912efbfc84889a721b58f881aa2f79bc4fa4fa93..f3371d18affeedb6422004601d6b6fd6ed7bc642 100644 (file)
@@ -14,8 +14,8 @@
 
 #include "mini.h"
 
-//#define ALLOW_PARTIAL_SHARING TRUE
-#define ALLOW_PARTIAL_SHARING FALSE
+#define ALLOW_PARTIAL_SHARING TRUE
+//#define ALLOW_PARTIAL_SHARING FALSE
 
 static void
 mono_class_unregister_image_generic_subclasses (MonoImage *image, gpointer user_data);
@@ -595,6 +595,41 @@ class_uninstantiated (MonoClass *class)
        return class;
 }
 
+static gboolean
+generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars,
+                                                 gboolean allow_partial)
+{
+       gboolean has_refs;
+       int i;
+
+       has_refs = FALSE;
+       for (i = 0; i < inst->type_argc; ++i) {
+               MonoType *type = inst->type_argv [i];
+
+               if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
+                       has_refs = TRUE;
+       }
+       for (i = 0; i < inst->type_argc; ++i) {
+               MonoType *type = inst->type_argv [i];
+
+               if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
+                       continue;
+               /*
+                * Allow non ref arguments, if there is at least one ref argument
+                * (partial sharing).
+                * FIXME: Allow more types
+                */
+               if (allow_partial && !type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)))
+                       continue;
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 /*
  * mono_is_partially_sharable_inst:
  *
@@ -658,6 +693,9 @@ get_shared_class (MonoClass *class)
                        g_free (type_argv);
 
                        return mono_class_inflate_generic_class (class->generic_class->container_class, &shared_context);
+               } else if (!generic_inst_is_sharable (inst, TRUE, FALSE)) {
+                       /* Happens for partially shared methods of nono-sharable generic class */
+                       return class;
                }
        }
 
@@ -684,7 +722,7 @@ mono_class_get_runtime_generic_context_template (MonoClass *class)
        if (template)
                return template;
 
-       g_assert (get_shared_class (class) == class);
+       //g_assert (get_shared_class (class) == class);
 
        template = alloc_template (class);
 
@@ -1356,41 +1394,6 @@ mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst
        return mrgctx;
 }
 
-static gboolean
-generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars,
-                                                 gboolean allow_partial)
-{
-       gboolean has_refs;
-       int i;
-
-       has_refs = FALSE;
-       for (i = 0; i < inst->type_argc; ++i) {
-               MonoType *type = inst->type_argv [i];
-
-               if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
-                       has_refs = TRUE;
-       }
-       for (i = 0; i < inst->type_argc; ++i) {
-               MonoType *type = inst->type_argv [i];
-
-               if (MONO_TYPE_IS_REFERENCE (type) || (allow_type_vars && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)))
-                       continue;
-               /*
-                * Allow non ref arguments, if there is at least one ref argument
-                * (partial sharing).
-                * FIXME: Allow more types
-                */
-               if (!type->byref && type->type == MONO_TYPE_I4 && has_refs && allow_partial)
-                       continue;
-
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
 /*
  * mono_generic_context_is_sharable_full:
  * @context: a generic context