update known-issues
[mono.git] / mono / metadata / reflection.c
index 12f932421e69ac92f409ef78765a13bf5ebefce3..442903f3b01fba43b1c6c34fd8a1bc4f89f8642e 100644 (file)
@@ -149,6 +149,7 @@ static void get_default_param_value_blobs (MonoMethod *method, char **blobs, gui
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
 static inline MonoType *dup_type (const MonoType *original);
 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
+static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
 
 #define mono_reflection_lock() EnterCriticalSection (&reflection_mutex)
 #define mono_reflection_unlock() LeaveCriticalSection (&reflection_mutex)
@@ -240,6 +241,21 @@ mp_g_malloc0 (MonoMemPool *mp, guint size)
                return g_malloc0 (size);
 }
 
+/**
+ * mp_string_to_utf8:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate
+ * memory from the C heap.
+ */
+static char *
+mp_string_to_utf8 (MonoMemPool *mp, MonoString *s)
+{
+       if (mp)
+               return mono_string_to_utf8_mp (mp, s);
+       else
+               return mono_string_to_utf8 (s);
+}
+
 #define mp_g_new(mp,struct_type, n_structs)            \
     ((struct_type *) mp_g_malloc (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
@@ -553,7 +569,7 @@ default_class_from_mono_type (MonoType *type)
        case MONO_TYPE_STRING:
                return mono_defaults.string_class;
        default:
-               g_warning ("implement me 0x%02x\n", type->type);
+               g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
                g_assert_not_reached ();
        }
        
@@ -2413,6 +2429,7 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
        table = &assembly->tables [MONO_TABLE_METHODSPEC];
 
        g_assert (method->is_inflated);
+       g_assert (!method->klass->generic_container);
        imethod = (MonoMethodInflated *) method;
        declaring = imethod->declaring;
 
@@ -6265,6 +6282,7 @@ _mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image,
 {
        gboolean type_resolve = FALSE;
        MonoType *type;
+       MonoImage *rootimage = image;
 
        if (info->assembly.name) {
                MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
@@ -6279,17 +6297,17 @@ _mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image,
                image = mono_defaults.corlib;
        }
 
-       type = mono_reflection_get_type (image, info, ignorecase, &type_resolve);
+       type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
        if (type == NULL && !info->assembly.name && image != mono_defaults.corlib) {
                image = mono_defaults.corlib;
-               type = mono_reflection_get_type (image, info, ignorecase, &type_resolve);
+               type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
        }
 
        return type;
 }
 
 static MonoType*
-mono_reflection_get_type_internal (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
+mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
 {
        MonoClass *klass;
        GList *mod;
@@ -6338,7 +6356,7 @@ mono_reflection_get_type_internal (MonoImage* image, MonoTypeNameParse *info, gb
                for (i = 0; i < info->type_arguments->len; i++) {
                        MonoTypeNameParse *subinfo = g_ptr_array_index (info->type_arguments, i);
 
-                       type_args [i] = _mono_reflection_get_type_from_info (subinfo, image, ignorecase);
+                       type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase);
                        if (!type_args [i]) {
                                g_free (type_args);
                                return NULL;
@@ -6385,14 +6403,19 @@ mono_reflection_get_type_internal (MonoImage* image, MonoTypeNameParse *info, gb
  */
 
 MonoType*
-mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
+mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
+       return mono_reflection_get_type_with_rootimage(image, image, info, ignorecase, type_resolve);
+}
+       
+MonoType*
+mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
 {
        MonoType *type;
        MonoReflectionAssembly *assembly;
        GString *fullName;
        GList *mod;
 
-       type = mono_reflection_get_type_internal (image, info, ignorecase);
+       type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase);
        if (type)
                return type;
        if (!mono_domain_has_type_resolve (mono_domain_get ()))
@@ -6425,7 +6448,7 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
                        if (abuilder->modules) {
                                for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
                                        MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
-                                       type = mono_reflection_get_type_internal (&mb->dynamic_image->image, info, ignorecase);
+                                       type = mono_reflection_get_type_internal (rootimage, &mb->dynamic_image->image, info, ignorecase);
                                        if (type)
                                                break;
                                }
@@ -6434,14 +6457,14 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
                        if (!type && abuilder->loaded_modules) {
                                for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
                                        MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
-                                       type = mono_reflection_get_type_internal (mod->image, info, ignorecase);
+                                       type = mono_reflection_get_type_internal (rootimage, mod->image, info, ignorecase);
                                        if (type)
                                                break;
                                }
                        }
                }
                else
-                       type = mono_reflection_get_type_internal (assembly->assembly->image, 
+                       type = mono_reflection_get_type_internal (rootimage, assembly->assembly->image, 
                                                                                                          info, ignorecase);
        }
        g_string_free (fullName, TRUE);
@@ -8271,6 +8294,11 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
 
                fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
 
+               if (!mono_type_is_valid_enum_basetype (fb->type->type)) {
+                       mono_loader_unlock ();
+                       return;
+               }
+
                klass->enum_basetype = fb->type->type;
                klass->element_class = my_mono_class_from_mono_type (klass->enum_basetype);
                if (!klass->element_class)
@@ -8419,10 +8447,11 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
        pm = (MonoMethodNormal*)m;
 
+       m->dynamic = dynamic;
        m->slot = -1;
        m->flags = rmb->attrs;
        m->iflags = rmb->iattrs;
-       m->name = dynamic ? mono_string_to_utf8 (rmb->name) : mono_string_to_utf8_mp (mp, rmb->name);
+       m->name = mp_string_to_utf8 (mp, rmb->name);
        m->klass = klass;
        m->signature = sig;
        m->skip_visibility = rmb->skip_visibility;
@@ -8581,7 +8610,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                }
 
                                if (pb->name)
-                                       method_aux->param_names [i] = dynamic ? mono_string_to_utf8 (pb->name) : mono_string_to_utf8_mp (mp, pb->name);
+                                       method_aux->param_names [i] = mp_string_to_utf8 (mp, pb->name);
                                if (pb->cattrs) {
                                        if (!method_aux->param_cattr)
                                                method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1);
@@ -8765,26 +8794,19 @@ mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **
        inst = g_new0 (MonoGenericInst, 1);
        inst->type_argc = type_argc;
        inst->type_argv = g_new0 (MonoType *, inst->type_argc);
-       inst->is_reference = 1;
 
        for (i = 0; i < inst->type_argc; ++i) {
                MonoType *t = dup_type (types [i]);
 
                if (!inst->is_open)
                        inst->is_open = mono_class_is_open_constructed_type (t);
-               if (inst->is_reference)
-                       inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
 
                inst->type_argv [i] = t;
        }
 
-       mono_loader_lock ();
-
        inst = mono_metadata_lookup_generic_inst (inst);
        gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
 
-       mono_loader_unlock ();
-
        return mono_generic_class_get_class (gclass);
 }
 
@@ -8808,11 +8830,12 @@ dup_type (const MonoType *original)
 MonoReflectionMethod*
 mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
 {
+       MonoClass *klass;
        MonoMethod *method, *inflated;
        MonoMethodInflated *imethod;
        MonoReflectionMethodBuilder *mb = NULL;
        MonoGenericContainer *container;
-       MonoGenericContext *context;
+       MonoGenericContext tmp_context;
        MonoGenericInst *ginst;
        int count, i;
 
@@ -8830,7 +8853,10 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                method = rmethod->method;
        }
 
-       method = mono_get_inflated_method (method);
+       klass = method->klass;
+
+       if (method->is_inflated)
+               method = ((MonoMethodInflated *) method)->declaring;
 
        count = mono_method_signature (method)->generic_param_count;
        if (count != mono_array_length (types))
@@ -8847,40 +8873,29 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        ginst = g_new0 (MonoGenericInst,1 );
        ginst->type_argc = count;
        ginst->type_argv = g_new0 (MonoType *, count);
-       ginst->is_reference = 1;
        for (i = 0; i < count; i++) {
                MonoReflectionType *garg = mono_array_get (types, gpointer, i);
                ginst->type_argv [i] = dup_type (garg->type);
 
                if (!ginst->is_open)
                        ginst->is_open = mono_class_is_open_constructed_type (ginst->type_argv [i]);
-               if (ginst->is_reference)
-                       ginst->is_reference = MONO_TYPE_IS_REFERENCE (ginst->type_argv [i]);
        }
        ginst = mono_metadata_lookup_generic_inst (ginst);
 
-       context = g_new0 (MonoGenericContext, 1);
-       if (method->klass->generic_class)
-               context->class_inst = method->klass->generic_class->context.class_inst;
-       context->method_inst = ginst;
-
-       inflated = g_hash_table_lookup (container->method_hash, context);
-       if (inflated) {
-               g_free (context);
+       tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+       tmp_context.method_inst = ginst;
 
+       inflated = g_hash_table_lookup (container->method_hash, &tmp_context);
+       if (inflated)
                return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
-       }
-
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
 
-       inflated = mono_class_inflate_generic_method (method, context);
+       inflated = mono_class_inflate_generic_method (method, &tmp_context);
        imethod = (MonoMethodInflated *) inflated;
 
        MOVING_GC_REGISTER (&imethod->reflection_info);
        imethod->reflection_info = rmethod;
 
-       g_hash_table_insert (container->method_hash, context, inflated);
+       g_hash_table_insert (container->method_hash, mono_method_get_context (inflated), inflated);
 
        return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
@@ -8889,6 +8904,7 @@ static MonoMethod *
 inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
 {
        MonoMethodInflated *imethod;
+       MonoGenericContext tmp_context;
        MonoGenericContext *context;
        MonoClass *klass;
 
@@ -8899,9 +8915,9 @@ inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoO
        if (method->generic_container) {
                g_assert (method->klass == klass->generic_class->container_class);
 
-               context = g_new0 (MonoGenericContext, 1);
-               context->class_inst = klass->generic_class->context.class_inst;
-               context->method_inst = method->generic_container->context.method_inst;
+               tmp_context.class_inst = klass->generic_class->context.class_inst;
+               tmp_context.method_inst = method->generic_container->context.method_inst;
+               context = &tmp_context;
        }
 
        imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context);
@@ -9388,11 +9404,16 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        typebuilder_setup_properties (klass);
 
        typebuilder_setup_events (klass);
-
+       
        klass->wastypebuilder = TRUE;
        mono_loader_unlock ();
        mono_domain_unlock (domain);
 
+       if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
+               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+               mono_raise_exception (mono_get_exception_type_load (tb->name, NULL));
+       }
+
        res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
        g_assert (res != (MonoReflectionType*)tb);
 
@@ -9566,6 +9587,16 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        mb->ilgen = NULL;
 }
 
+void
+mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+       g_assert (mb);
+
+       if (mb->mhandle)
+               mono_runtime_free_method (
+                       mono_object_get_domain ((MonoObject*)mb), mb->mhandle);
+}
+
 /**
  * mono_reflection_lookup_dynamic_token:
  *