[reflection] Use handles for several more icalls (#4098)
[mono.git] / mono / metadata / metadata.c
index ab0911bc677f89e1459c8f7476aff317c5e4eccf..2fdcb1f6bffea82af0322bf60f7c5f755385ca1b 100644 (file)
@@ -2789,6 +2789,9 @@ free_inflated_method (MonoMethodInflated *imethod)
        if (method->signature)
                mono_metadata_free_inflated_signature (method->signature);
 
+       if (method->wrapper_type)
+               g_free (((MonoMethodWrapper*)method)->method_data);
+
        g_free (method);
 }
 
@@ -2806,8 +2809,6 @@ static void
 free_generic_class (MonoGenericClass *gclass)
 {
        /* The gclass itself is allocated from the image set mempool */
-       if (gclass->is_dynamic)
-               mono_reflection_free_dynamic_generic_class (gclass);
        if (gclass->cached_class && gclass->cached_class->interface_id)
                mono_unload_interface_id (gclass->cached_class);
 }
@@ -2890,8 +2891,6 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
        gboolean is_open;
        int i;
        int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
-       CollectData data;
-       MonoImageSet *set;
 
        for (i = 0; i < type_argc; ++i)
                if (mono_class_is_open_constructed_type (type_argv [i]))
@@ -2904,9 +2903,34 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
        ginst->type_argc = type_argc;
        memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));
 
+       return mono_metadata_get_canonical_generic_inst (ginst);
+}
+
+
+/**
+ * mono_metadata_get_canonical_generic_inst:
+ * @candidate: an arbitrary generic instantiation
+ *
+ * Returns the canonical generic instantiation that represents the given
+ * candidate by identifying the image set for the candidate instantiation and
+ * finding the instance in the image set or adding a copy of the given instance
+ * to the image set.
+ *
+ * The returned MonoGenericInst has its own copy of the list of types.  The list
+ * passed in the argument can be freed, modified or disposed of.
+ *
+ */
+MonoGenericInst *
+mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate)
+{
+       CollectData data;
+       int type_argc = candidate->type_argc;
+       gboolean is_open = candidate->is_open;
+       MonoImageSet *set;
+
        collect_data_init (&data);
 
-       collect_ginst_images (ginst, &data);
+       collect_ginst_images (candidate, &data);
 
        set = get_image_set (data.images, data.nimages);
 
@@ -2914,8 +2938,9 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
 
        mono_image_set_lock (set);
 
-       ginst = (MonoGenericInst *)g_hash_table_lookup (set->ginst_cache, ginst);
+       MonoGenericInst *ginst = (MonoGenericInst *)g_hash_table_lookup (set->ginst_cache, candidate);
        if (!ginst) {
+               int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
                ginst = (MonoGenericInst *)mono_image_set_alloc0 (set, size);
 #ifndef MONO_SMALL_CONFIG
                ginst->id = ++next_generic_inst_id;
@@ -2923,8 +2948,8 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
                ginst->is_open = is_open;
                ginst->type_argc = type_argc;
 
-               for (i = 0; i < type_argc; ++i)
-                       ginst->type_argv [i] = mono_metadata_type_dup (NULL, type_argv [i]);
+               for (int i = 0; i < type_argc; ++i)
+                       ginst->type_argv [i] = mono_metadata_type_dup (NULL, candidate->type_argv [i]);
 
                g_hash_table_insert (set->ginst_cache, ginst, ginst);
        }
@@ -2936,7 +2961,7 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
 static gboolean
 mono_metadata_is_type_builder_generic_type_definition (MonoClass *container_class, MonoGenericInst *inst, gboolean is_dynamic)
 {
-       MonoGenericContainer *container = container_class->generic_container
+       MonoGenericContainer *container = mono_class_get_generic_container (container_class)
 
        if (!is_dynamic || container_class->wastypebuilder || container->type_argc != inst->type_argc)
                return FALSE;
@@ -2958,6 +2983,8 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst
        MonoImageSet *set;
        CollectData data;
 
+       g_assert (mono_class_get_generic_container (container_class)->type_argc == inst->type_argc);
+
        memset (&helper, 0, sizeof(helper)); // act like g_new0
        helper.container_class = container_class;
        helper.context.class_inst = inst;
@@ -2984,20 +3011,16 @@ mono_metadata_lookup_generic_class (MonoClass *container_class, MonoGenericInst
                return gclass;
        }
 
-       if (is_dynamic) {
-               MonoDynamicGenericClass *dgclass = mono_image_set_new0 (set, MonoDynamicGenericClass, 1);
-               gclass = &dgclass->generic_class;
+       gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
+       if (is_dynamic)
                gclass->is_dynamic = 1;
-       } else {
-               gclass = mono_image_set_new0 (set, MonoGenericClass, 1);
-       }
 
        gclass->is_tb_open = is_tb_open;
        gclass->container_class = container_class;
        gclass->context.class_inst = inst;
        gclass->context.method_inst = NULL;
        gclass->owner = set;
-       if (inst == container_class->generic_container->context.class_inst && !is_tb_open)
+       if (inst == mono_class_get_generic_container (container_class)->context.class_inst && !is_tb_open)
                gclass->cached_class = container_class;
 
        g_hash_table_insert (set->gclass_cache, gclass, gclass);
@@ -3092,7 +3115,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
                return FALSE;
 
        gklass = mono_class_from_mono_type (gtype);
-       if (!gklass->generic_container) {
+       if (!mono_class_is_gtd (gklass)) {
                mono_error_set_bad_image (error, m, "Generic instance with non-generic definition");
                return FALSE;
        }
@@ -4807,7 +4830,7 @@ static gboolean
 _mono_metadata_generic_class_container_equal (const MonoGenericClass *g1, MonoClass *c2, gboolean signature_only)
 {
        MonoGenericInst *i1 = g1->context.class_inst;
-       MonoGenericInst *i2 = c2->generic_container->context.class_inst;
+       MonoGenericInst *i2 = mono_class_get_generic_container (c2)->context.class_inst;
 
        if (!mono_metadata_class_equal (g1->container_class, c2, signature_only))
                return FALSE;
@@ -4962,12 +4985,12 @@ mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only
 {
        if (c1 == c2)
                return TRUE;
-       if (c1->generic_class && c2->generic_class)
-               return _mono_metadata_generic_class_equal (c1->generic_class, c2->generic_class, signature_only);
-       if (c1->generic_class && c2->generic_container)
-               return _mono_metadata_generic_class_container_equal (c1->generic_class, c2, signature_only);
-       if (c1->generic_container && c2->generic_class)
-               return _mono_metadata_generic_class_container_equal (c2->generic_class, c1, signature_only);
+       if (mono_class_is_ginst (c1) && mono_class_is_ginst (c2))
+               return _mono_metadata_generic_class_equal (mono_class_get_generic_class (c1), mono_class_get_generic_class (c2), signature_only);
+       if (mono_class_is_ginst (c1) && mono_class_is_gtd (c2))
+               return _mono_metadata_generic_class_container_equal (mono_class_get_generic_class (c1), c2, signature_only);
+       if (mono_class_is_gtd (c1) && mono_class_is_ginst (c2))
+               return _mono_metadata_generic_class_container_equal (mono_class_get_generic_class (c2), c1, signature_only);
        if ((c1->byval_arg.type == MONO_TYPE_VAR) && (c2->byval_arg.type == MONO_TYPE_VAR))
                return mono_metadata_generic_param_equal_internal (
                        c1->byval_arg.data.generic_param, c2->byval_arg.data.generic_param, signature_only);
@@ -5815,6 +5838,9 @@ handle_enum:
                        case MONO_NATIVE_TBSTR:
                                *conv = MONO_MARSHAL_CONV_STR_TBSTR;
                                return MONO_NATIVE_TBSTR;
+                       case MONO_NATIVE_UTF8STR:
+                               *conv = MONO_MARSHAL_CONV_STR_UTF8STR;
+                               return MONO_NATIVE_UTF8STR;
                        case MONO_NATIVE_BYVALTSTR:
                                if (unicode)
                                        *conv = MONO_MARSHAL_CONV_STR_BYVALWSTR;
@@ -6069,6 +6095,21 @@ mono_guid_to_string (const guint8 *guid)
                                guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
 }
 
+/**
+ * mono_guid_to_string_minimal:
+ *
+ * Converts a 16 byte Microsoft GUID to lower case no '-' representation..
+ */
+char *
+mono_guid_to_string_minimal (const guint8 *guid)
+{
+       return g_strdup_printf ("%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+                               guid[3], guid[2], guid[1], guid[0],
+                               guid[5], guid[4],
+                               guid[7], guid[6],
+                               guid[8], guid[9],
+                               guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
+}
 static gboolean
 get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGenericContainer *container, MonoError *error)
 {
@@ -6444,6 +6485,12 @@ mono_type_is_reference (MonoType *type)
                !mono_metadata_generic_class_is_valuetype (type->data.generic_class))));
 }
 
+mono_bool
+mono_type_is_generic_parameter (MonoType *type)
+{
+       return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
+}
+
 /**
  * mono_signature_get_return_type:
  * @sig: the method signature inspected
@@ -6589,10 +6636,10 @@ mono_metadata_get_corresponding_field_from_generic_type_definition (MonoClassFie
        MonoClass *gtd;
        int offset;
 
-       if (!field->parent->generic_class)
+       if (!mono_class_is_ginst (field->parent))
                return field;
 
-       gtd = field->parent->generic_class->container_class;
+       gtd = mono_class_get_generic_class (field->parent)->container_class;
        offset = field - field->parent->fields;
        return gtd->fields + offset;
 }
@@ -6607,12 +6654,12 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
        MonoClass *gtd;
        int offset;
 
-       if (!event->parent->generic_class)
+       if (!mono_class_is_ginst (event->parent))
                return event;
 
-       gtd = event->parent->generic_class->container_class;
-       offset = event - event->parent->ext->events;
-       return gtd->ext->events + offset;
+       gtd = mono_class_get_generic_class (event->parent)->container_class;
+       offset = event - mono_class_get_event_info (event->parent)->events;
+       return mono_class_get_event_info (gtd)->events + offset;
 }
 
 /*
@@ -6622,15 +6669,17 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
 MonoProperty*
 mono_metadata_get_corresponding_property_from_generic_type_definition (MonoProperty *property)
 {
+       MonoClassPropertyInfo *info;
        MonoClass *gtd;
        int offset;
 
-       if (!property->parent->generic_class)
+       if (!mono_class_is_ginst (property->parent))
                return property;
 
-       gtd = property->parent->generic_class->container_class;
-       offset = property - property->parent->ext->properties;
-       return gtd->ext->properties + offset;
+       info = mono_class_get_property_info (property->parent);
+       gtd = mono_class_get_generic_class (property->parent)->container_class;
+       offset = property - info->properties;
+       return mono_class_get_property_info (gtd)->properties + offset;
 }
 
 MonoWrapperCaches*