[runtime] Clean mono_init_internal hacks. Moved to mono_class_setup_mono_type / mono_...
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 28 Nov 2016 22:54:18 +0000 (14:54 -0800)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 28 Nov 2016 23:10:30 +0000 (15:10 -0800)
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/domain.c

index 446db537ef9301f2999c5861c8efdc12a1cb2fae..5ff799cc626c810b7ccb58c4a6c4f8da2c4170c4 100644 (file)
@@ -1103,8 +1103,6 @@ typedef struct {
        MonoClass *argumenthandle_class;
        MonoClass *monitor_class;
        MonoClass *generic_ilist_class;
-       MonoClass *generic_icollection_class;
-       MonoClass *generic_ienumerable_class;
        MonoClass *generic_nullable_class;
        MonoClass *handleref_class;
        MonoClass *attribute_class;
index a332083ca1a6250ae7dded897b07f945c0395d5b..93bc797cc970bee9443e2faec2492f9f7fd522b6 100644 (file)
@@ -5576,8 +5576,22 @@ mono_class_setup_mono_type (MonoClass *klass)
                klass->this_arg.type = (MonoTypeEnum)t;
        }
 
-       if (MONO_CLASS_IS_INTERFACE (klass))
+       if (MONO_CLASS_IS_INTERFACE (klass)) {
                klass->interface_id = mono_get_unique_iid (klass);
+
+               if (is_corlib && !strcmp (nspace, "System.Collections.Generic")) {
+                       //FIXME IEnumerator needs to be special because GetEnumerator uses magic under the hood
+                   /* FIXME: System.Array/InternalEnumerator don't need all this interface fabrication machinery.
+                   * MS returns diferrent types based on which instance is called. For example:
+                   *   object obj = new byte[10][];
+                   *   Type a = ((IEnumerable<byte[]>)obj).GetEnumerator ().GetType ();
+                   *   Type b = ((IEnumerable<IList<byte>>)obj).GetEnumerator ().GetType ();
+                   *   a != b ==> true
+                       */
+                       if (!strcmp (name, "IList`1") || !strcmp (name, "ICollection`1") || !strcmp (name, "IEnumerable`1") || !strcmp (name, "IEnumerator`1"))
+                               klass->is_array_special_interface = 1;
+               }
+       }
 }
 
 #ifndef DISABLE_COM
@@ -5916,6 +5930,42 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError
 #endif
 
        klass->cast_class = klass->element_class = klass;
+       if (mono_is_corlib_image (klass->image)) {
+               switch (klass->byval_arg.type) {
+                       case MONO_TYPE_I1:
+                               if (mono_defaults.byte_class)
+                                       klass->cast_class = mono_defaults.byte_class;
+                               break;
+                       case MONO_TYPE_U1:
+                               if (mono_defaults.sbyte_class)
+                                       mono_defaults.sbyte_class = klass;
+                               break;
+                       case MONO_TYPE_I2:
+                               if (mono_defaults.uint16_class)
+                                       mono_defaults.uint16_class = klass;
+                               break;
+                       case MONO_TYPE_U2:
+                               if (mono_defaults.int16_class)
+                                       klass->cast_class = mono_defaults.int16_class;
+                               break;
+                       case MONO_TYPE_I4:
+                               if (mono_defaults.uint32_class)
+                                       mono_defaults.uint32_class = klass;
+                               break;
+                       case MONO_TYPE_U4:
+                               if (mono_defaults.int32_class)
+                                       klass->cast_class = mono_defaults.int32_class;
+                               break;
+                       case MONO_TYPE_I8:
+                               if (mono_defaults.uint64_class)
+                                       mono_defaults.uint64_class = klass;
+                               break;
+                       case MONO_TYPE_U8:
+                               if (mono_defaults.int64_class)
+                                       klass->cast_class = mono_defaults.int64_class;
+                               break;
+               }
+       }
 
        if (!klass->enumtype) {
                if (!mono_metadata_interfaces_from_typedef_full (
index e51ce5ffbcc9bc11fcdca4ef7deed1a1caec6a4e..020b0dd00c4406bc0d482714b2af17e65836b0d6 100644 (file)
@@ -673,13 +673,6 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        mono_defaults.uint64_class = mono_class_load_from_name (
                 mono_defaults.corlib, "System", "UInt64");
 
-       //XXX find a better place, which kinda doesn't exists as those types depend on each other.
-       mono_defaults.uint32_class->cast_class = mono_defaults.int32_class;
-       mono_defaults.uint16_class->cast_class = mono_defaults.int16_class;
-       mono_defaults.sbyte_class->cast_class = mono_defaults.byte_class;
-       mono_defaults.uint64_class->cast_class = mono_defaults.int64_class;
-
-
        mono_defaults.single_class = mono_class_load_from_name (
                 mono_defaults.corlib, "System", "Single");
 
@@ -808,27 +801,10 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
        mono_class_init (mono_defaults.array_class);
        mono_defaults.generic_nullable_class = mono_class_load_from_name (
                mono_defaults.corlib, "System", "Nullable`1");
-       mono_defaults.generic_ireadonlylist_class = mono_class_load_from_name (
-               mono_defaults.corlib, "System.Collections.Generic", "IReadOnlyList`1");
-
-       //IList, ICollection, IEnumerable
        mono_defaults.generic_ilist_class = mono_class_load_from_name (
                mono_defaults.corlib, "System.Collections.Generic", "IList`1");
-       mono_defaults.generic_icollection_class = mono_class_load_from_name (
-               mono_defaults.corlib, "System.Collections.Generic", "ICollection`1");
-       mono_defaults.generic_ienumerable_class = mono_class_load_from_name (
-               mono_defaults.corlib, "System.Collections.Generic", "IEnumerable`1");
-
-       //XXX This is a hack, there's probably a better place to do this. Probably in mono_class_create_from_typedef
-       mono_defaults.generic_ilist_class->is_array_special_interface = 1;
-       mono_defaults.generic_icollection_class->is_array_special_interface = 1;
-       mono_defaults.generic_ienumerable_class->is_array_special_interface = 1;
-
-       //FIXME IEnumerator needs to be special because GetEnumerator uses magic under the hood
-       MonoClass *tmp = mono_class_load_from_name (
-               mono_defaults.corlib, "System.Collections.Generic", "IEnumerator`1");
-       tmp->is_array_special_interface = 1;
-
+       mono_defaults.generic_ireadonlylist_class = mono_class_load_from_name (
+               mono_defaults.corlib, "System.Collections.Generic", "IReadOnlyList`1");
 
        mono_defaults.threadpool_wait_callback_class = mono_class_load_from_name (
                mono_defaults.corlib, "System.Threading", "_ThreadPoolWaitCallback");