Tue Aug 21 16:40:04 CEST 2007 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / reflection.c
index f626ee12168d172bf7d634ce70bf6db80d3e2d9b..6a9a9fd8a383778c642be3cbd19652c1cf485d9b 100644 (file)
@@ -147,8 +147,8 @@ static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **h
 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
 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 +240,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 +568,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 ();
        }
        
@@ -564,17 +579,17 @@ static void
 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
 {
        int i;
+       MonoGenericInst *class_inst;
 
-       if (!gclass) {
-               g_assert_not_reached ();
-               return;
-       }
+       g_assert (gclass);
+
+       class_inst = gclass->context.class_inst;
 
        sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
        encode_type (assembly, &gclass->container_class->byval_arg, buf);
-       sigbuffer_add_value (buf, gclass->inst->type_argc);
-       for (i = 0; i < gclass->inst->type_argc; ++i)
-               encode_type (assembly, gclass->inst->type_argv [i], buf);
+       sigbuffer_add_value (buf, class_inst->type_argc);
+       for (i = 0; i < class_inst->type_argc; ++i)
+               encode_type (assembly, class_inst->type_argv [i], buf);
 
 }
 
@@ -1066,11 +1081,21 @@ static GHashTable *dynamic_custom_attrs = NULL;
 static MonoCustomAttrInfo*
 lookup_custom_attr (void *member)
 {
-       MonoCustomAttrInfo *ainfo;
+       MonoCustomAttrInfo *ainfo, *res;
+       int size;
+
        mono_reflection_lock ();
        ainfo = g_hash_table_lookup (dynamic_custom_attrs, member);
        mono_reflection_unlock ();
-       return ainfo;
+
+       if (ainfo) {
+               /* Need to copy since it will be freed later */
+               size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+               res = g_malloc0 (size);
+               memcpy (res, ainfo, size);
+               return res;
+       }
+       return NULL;
 }
 
 static gboolean
@@ -2366,11 +2391,11 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
 }
 
 static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmethod)
+encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
 {
        SigBuffer buf;
        int i;
-       guint32 nparams =  gmethod->inst->type_argc;
+       guint32 nparams = context->method_inst->type_argc;
        guint32 idx;
 
        if (!assembly->save)
@@ -2384,7 +2409,7 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmetho
        sigbuffer_add_value (&buf, nparams);
 
        for (i = 0; i < nparams; i++)
-               encode_type (assembly, gmethod->inst->type_argv [i], &buf);
+               encode_type (assembly, context->method_inst->type_argv [i], &buf);
 
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
@@ -2403,6 +2428,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;
 
@@ -2423,7 +2449,7 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
                g_assert_not_reached ();
        }
 
-       sig = encode_generic_method_sig (assembly, mono_method_get_context (method)->gmethod);
+       sig = encode_generic_method_sig (assembly, mono_method_get_context (method));
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
@@ -2442,7 +2468,6 @@ static guint32
 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
 {
        MonoMethodInflated *imethod;
-       MonoMethod *inflated;
        guint32 token;
        
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
@@ -2450,16 +2475,15 @@ mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
                return token;
 
        g_assert (method->is_inflated);
-       inflated = mono_get_inflated_method (method);
-       imethod = (MonoMethodInflated *) inflated;
+       imethod = (MonoMethodInflated *) method;
 
        if (mono_method_signature (imethod->declaring)->generic_param_count) {
-               token = method_encode_methodspec (assembly, inflated);
+               token = method_encode_methodspec (assembly, method);
        } else {
                guint32 sig = method_encode_signature (
                        assembly, mono_method_signature (imethod->declaring));
                token = mono_image_get_memberref_token (
-                       assembly, &inflated->klass->byval_arg, inflated->name, sig);
+                       assembly, &method->klass->byval_arg, method->name, sig);
        }
 
        g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
@@ -2472,8 +2496,6 @@ mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
        MonoMethodInflated *imethod = (MonoMethodInflated *) m;
        guint32 sig, token;
 
-       m = mono_get_inflated_method (m);
-
        sig = method_encode_signature (assembly, mono_method_signature (imethod->declaring));
        token = mono_image_get_memberref_token (
                assembly, &m->klass->byval_arg, m->name, sig);
@@ -4999,7 +5021,7 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) {
 }
 
 MonoReflectionModule *
-mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
+mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
 {
        char *name;
        MonoImage *image;
@@ -5007,6 +5029,7 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
        MonoDynamicAssembly *assembly;
        guint32 module_count;
        MonoImage **new_modules;
+       gboolean *new_modules_loaded;
        
        name = mono_string_to_utf8 (fileName);
 
@@ -5028,14 +5051,19 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
 
        module_count = image->assembly->image->module_count;
        new_modules = g_new0 (MonoImage *, module_count + 1);
+       new_modules_loaded = g_new0 (gboolean, module_count + 1);
 
        if (image->assembly->image->modules)
                memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
+       if (image->assembly->image->modules_loaded)
+               memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
        new_modules [module_count] = image;
+       new_modules_loaded [module_count] = TRUE;
        mono_image_addref (image);
 
        g_free (image->assembly->image->modules);
        image->assembly->image->modules = new_modules;
+       image->assembly->image->modules_loaded = new_modules_loaded;
        image->assembly->image->module_count ++;
 
        mono_assembly_load_references (image, &status);
@@ -5312,13 +5340,16 @@ mymono_metadata_type_equal (MonoType *t1, MonoType *t2)
                return t1->data.array->eklass == t2->data.array->eklass;
        case MONO_TYPE_GENERICINST: {
                int i;
-               if (t1->data.generic_class->inst->type_argc != t2->data.generic_class->inst->type_argc)
+               MonoGenericInst *i1 = t1->data.generic_class->context.class_inst;
+               MonoGenericInst *i2 = t2->data.generic_class->context.class_inst;
+               if (i1->type_argc != i2->type_argc)
                        return FALSE;
                if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg,
                                               &t2->data.generic_class->container_class->byval_arg))
                        return FALSE;
-               for (i = 0; i < t1->data.generic_class->inst->type_argc; ++i) {
-                       if (!mono_metadata_type_equal (t1->data.generic_class->inst->type_argv [i], t2->data.generic_class->inst->type_argv [i]))
+               /* FIXME: we should probably just compare the instance pointers directly.  */
+               for (i = 0; i < i1->type_argc; ++i) {
+                       if (!mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i]))
                                return FALSE;
                }
                return TRUE;
@@ -5352,7 +5383,7 @@ mymono_metadata_type_hash (MonoType *t1)
                return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
        case MONO_TYPE_GENERICINST: {
                int i;
-               MonoGenericInst *inst = t1->data.generic_class->inst;
+               MonoGenericInst *inst = t1->data.generic_class->context.class_inst;
                hash += g_str_hash (t1->data.generic_class->container_class->name);
                hash *= 13;
                for (i = 0; i < inst->type_argc; ++i) {
@@ -5506,7 +5537,6 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
        if (method->is_inflated) {
                MonoReflectionGenericMethod *gret;
 
-               method = mono_get_inflated_method (method);
                refclass = method->klass;
                CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
                if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) {
@@ -5559,11 +5589,12 @@ MonoReflectionField*
 mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
 {
        MonoReflectionField *res;
-       MonoClass *oklass;
+       static MonoClass *monofield_klass;
 
        CHECK_OBJECT (MonoReflectionField *, field, klass);
-       oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoField");
-       res = (MonoReflectionField *)mono_object_new (domain, oklass);
+       if (!monofield_klass)
+               monofield_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoField");
+       res = (MonoReflectionField *)mono_object_new (domain, monofield_klass);
        res->klass = klass;
        res->field = field;
        MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
@@ -5588,11 +5619,12 @@ MonoReflectionProperty*
 mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *property)
 {
        MonoReflectionProperty *res;
-       MonoClass *oklass;
+       static MonoClass *monoproperty_klass;
 
        CHECK_OBJECT (MonoReflectionProperty *, property, klass);
-       oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoProperty");
-       res = (MonoReflectionProperty *)mono_object_new (domain, oklass);
+       if (!monoproperty_klass)
+               monoproperty_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoProperty");
+       res = (MonoReflectionProperty *)mono_object_new (domain, monoproperty_klass);
        res->klass = klass;
        res->property = property;
        CACHE_OBJECT (MonoReflectionProperty *, property, res, klass);
@@ -5611,11 +5643,12 @@ MonoReflectionEvent*
 mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
 {
        MonoReflectionEvent *res;
-       MonoClass *oklass;
+       static MonoClass *monoevent_klass;
 
        CHECK_OBJECT (MonoReflectionEvent *, event, klass);
-       oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
-       res = (MonoReflectionEvent *)mono_object_new (domain, oklass);
+       if (!monoevent_klass)
+               monoevent_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
+       res = (MonoReflectionEvent *)mono_object_new (domain, monoevent_klass);
        res->klass = klass;
        res->event = event;
        CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
@@ -5827,13 +5860,13 @@ MonoObject *
 mono_get_dbnull_object (MonoDomain *domain)
 {
        MonoObject *obj;
-       MonoClass *klass;
        static MonoClassField *dbnull_value_field = NULL;
        
        if (!dbnull_value_field) {
-               klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
-               mono_class_init (klass);
-               dbnull_value_field = mono_class_get_field_from_name (klass, "Value");
+               MonoClass *dbnull_klass;
+               dbnull_klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
+               mono_class_init (dbnull_klass);
+               dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
                g_assert (dbnull_value_field);
        }
        obj = mono_field_get_value_object (domain, dbnull_value_field, NULL); 
@@ -6243,6 +6276,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);
@@ -6257,17 +6291,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;
@@ -6316,7 +6350,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;
@@ -6363,14 +6397,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 ()))
@@ -6403,7 +6442,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;
                                }
@@ -6412,14 +6451,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);
@@ -6658,6 +6697,9 @@ handle_type:
                        int etype = *p;
                        p ++;
 
+                       if (etype == 0x51)
+                               /* See Partition II, Appendix B3 */
+                               etype = MONO_TYPE_OBJECT;
                        type = MONO_TYPE_SZARRAY;
                        simple_type.type = etype;
                        tklass = mono_class_from_mono_type (&simple_type);
@@ -6975,7 +7017,6 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
 {
        MonoArray *typedargs, *namedargs;
        MonoClass *attrklass;
-       static MonoClass *klass;
        static MonoMethod *ctor;
        MonoDomain *domain;
        MonoObject *attr;
@@ -6985,16 +7026,14 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
        void *params [3];
 
        mono_class_init (method->klass);
-       
-       if (!klass)
-               klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
+
        if (!ctor)
-               ctor = mono_class_get_method_from_name (klass, ".ctor", 3);
-       
+               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+
        domain = mono_domain_get ();
        if (len == 0) {
                /* This is for Attributes with no parameters */
-               attr = mono_object_new (domain, klass);
+               attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
                params [0] = mono_method_get_object (domain, method, NULL);
                params [1] = params [2] = NULL;
                mono_runtime_invoke (method, attr, params, NULL);
@@ -7081,7 +7120,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
                }
                g_free (name);
        }
-       attr = mono_object_new (domain, klass);
+       attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
        params [0] = mono_method_get_object (domain, method, NULL);
        params [1] = typedargs;
        params [2] = namedargs;
@@ -7093,12 +7132,10 @@ MonoArray*
 mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
 {
        MonoArray *result;
-       MonoClass *klass;
        MonoObject *attr;
        int i;
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
-       result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs);
+       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
                attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
                mono_array_setref (result, i, attr);
@@ -7111,7 +7148,6 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
 {
        MonoArray *result;
        MonoObject *attr;
-       MonoClass *klass;
        int i, n;
 
        n = 0;
@@ -7120,8 +7156,7 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
                        n ++;
        }
 
-       klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
-       result = mono_array_new (mono_domain_get (), klass, n);
+       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, n);
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
                if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
@@ -7137,14 +7172,10 @@ static MonoArray*
 mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
 {
        MonoArray *result;
-       static MonoClass *klass;
        MonoObject *attr;
        int i;
-
-       if (!klass)
-               klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
        
-       result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs);
+       result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
                attr = create_custom_attr_data (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
                mono_array_setref (result, i, attr);
@@ -7152,6 +7183,11 @@ mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
        return result;
 }
 
+/**
+ * mono_custom_attrs_from_index:
+ *
+ * Returns: NULL if no attributes are found or if a loading error occurs.
+ */
 MonoCustomAttrInfo*
 mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
 {
@@ -7195,8 +7231,12 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
                        break;
                }
                ainfo->attrs [i].ctor = mono_get_method (image, mtoken, NULL);
-               if (!ainfo->attrs [i].ctor)
-                       g_error ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
+               if (!ainfo->attrs [i].ctor) {
+                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
+                       g_list_free (list);
+                       g_free (ainfo);
+                       return NULL;
+               }
                data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
                ainfo->attrs [i].data_size = mono_metadata_decode_value (data, &data);
                ainfo->attrs [i].data = (guchar*)data;
@@ -7314,10 +7354,19 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
        MonoReflectionMethodAux *aux;
 
        if (method->klass->image->dynamic) {
+               MonoCustomAttrInfo *res, *ainfo;
+               int size;
+
                aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (!aux || !aux->param_cattr)
                        return NULL;
-               return aux->param_cattr [param];
+
+               /* Need to copy since it will be freed later */
+               ainfo = aux->param_cattr [param];
+               size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+               res = g_malloc0 (size);
+               memcpy (res, ainfo, size);
+               return res;
        }
 
        image = method->klass->image;
@@ -7423,8 +7472,8 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
                cinfo = mono_custom_attrs_from_method (rmethod->method);
        } else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
-               MonoMethod *method = mono_get_inflated_method (((MonoReflectionMethod*)obj)->method);
-               cinfo = mono_custom_attrs_from_method (method);
+               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
+               cinfo = mono_custom_attrs_from_method (rmethod->method);
        } else if (strcmp ("ParameterInfo", klass->name) == 0) {
                MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
                MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
@@ -7460,7 +7509,8 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
  *
  * Return an array with all the custom attributes defined of the
  * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes 
- * of that type are returned. The objects are fully build.
+ * of that type are returned. The objects are fully build. Return NULL if a loading error
+ * occurs.
  */
 MonoArray*
 mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
@@ -7477,9 +7527,9 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
        } else {
-               MonoClass *klass;
-               klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
-               result = mono_array_new (mono_domain_get (), klass, 0);
+               if (mono_loader_get_last_error ())
+                       return NULL;
+               result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, 0);
        }
 
        return result;
@@ -7490,7 +7540,8 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
  * @obj: a reflection object handle
  *
  * Return an array with all the custom attributes defined of the
- * reflection handle @obj. The objects are fully build.
+ * reflection handle @obj. The objects are fully build. Return NULL if a loading error
+ * occurs.
  */
 MonoArray*
 mono_reflection_get_custom_attrs (MonoObject *obj)
@@ -7517,11 +7568,8 @@ mono_reflection_get_custom_attrs_data (MonoObject *obj)
                result = mono_custom_attrs_data_construct (cinfo);
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
-       } else {
-               MonoClass *klass;
-               klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
-               result = mono_array_new (mono_domain_get (), klass, 0);
-       }
+       } else
+               result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, 0);
 
        return result;
 }
@@ -7851,7 +7899,11 @@ handle_type:
                        goto handle_enum;
                } else if (klass->rank == 1) {
                        *p++ = 0x1D;
-                       *p++ = klass->element_class->byval_arg.type;
+                       if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
+                               /* See Partition II, Appendix B3 */
+                               *p++ = 0x51;
+                       else
+                               *p++ = klass->element_class->byval_arg.type;
                        encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL);
                        break;
                } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
@@ -8236,6 +8288,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)
@@ -8384,10 +8441,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;
@@ -8491,7 +8549,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        container->parent = klass->generic_container;
                        container->context.class_inst = klass->generic_container->context.class_inst;
                }
-               container->context.gmethod = mono_get_shared_generic_method (container);
+               container->context.method_inst = mono_get_shared_generic_inst (container);
        }
 
        if (rmb->refs) {
@@ -8520,7 +8578,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                if ((i > 0) && (pb->attrs)) {
                                        /* Make a copy since it might point to a shared type structure */
                                        /* FIXME: Alloc this from a mempool */
-                                       m->signature->params [i - 1] = g_memdup (m->signature->params [i - 1], sizeof (MonoType) + ((m->signature->params [i - 1]->num_mods - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod)));
+                                       m->signature->params [i - 1] = mono_metadata_type_dup (NULL, m->signature->params [i - 1]);
                                        m->signature->params [i - 1]->attrs = pb->attrs;
                                }
 
@@ -8546,7 +8604,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);
@@ -8673,11 +8731,9 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
 {
        MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
-       MonoGenericClass *gclass, *cached;
        gboolean is_dynamic = FALSE;
        MonoDomain *domain;
-       MonoType *geninst;
-       int i;
+       MonoClass *geninst;
 
        mono_loader_lock ();
 
@@ -8713,162 +8769,37 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
                is_dynamic = TRUE;
        }
 
-       if (is_dynamic) {
-               MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1);
-               gclass = &dgclass->generic_class;
-               gclass->is_dynamic = TRUE;
-       } else {
-               gclass = g_new0 (MonoGenericClass, 1);
-       }
-
-       gclass->inst = g_new0 (MonoGenericInst, 1);
-
-       gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
-       gclass->inst->is_reference = 1;
-
-       for (i = 0; i < gclass->inst->type_argc; ++i) {
-               MonoType *t = dup_type (types [i]);
-
-               if (!gclass->inst->is_open)
-                       gclass->inst->is_open = mono_class_is_open_constructed_type (t);
-               if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
-               gclass->inst->type_argv [i] = t;
-       }
-
-       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
-       gclass->container_class = klass;
-
-       geninst = g_new0 (MonoType, 1);
-       geninst->type = MONO_TYPE_GENERICINST;
-
-       cached = mono_metadata_lookup_generic_class (gclass);
-       if (cached) {
-               g_free (gclass);
-               mono_loader_unlock ();
-               geninst->data.generic_class = cached;
-               return geninst;
-       }
-
-       geninst->data.generic_class = gclass;
-
        mono_loader_unlock ();
 
-       return geninst;
+       geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);
+
+       return &geninst->byval_arg;
 }
 
-MonoType*
-mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types)
+MonoClass*
+mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
 {
-       MonoClass *klass;
-       MonoGenericClass *gclass, *cached;
-       MonoType *geninst;
-       int i;
-
-       klass = mono_class_from_mono_type (type);
-       if (!klass->generic_container && !klass->generic_class &&
-           !(klass->nested_in && klass->nested_in->generic_container))
-               return NULL;
-
-       mono_loader_lock ();
-
-       gclass = g_new0 (MonoGenericClass, 1);
-
-       gclass->inst = g_new0 (MonoGenericInst, 1);
-       gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
-       gclass->inst->is_reference = 1;
-
-       for (i = 0; i < gclass->inst->type_argc; ++i) {
-               MonoType *t = dup_type (types [i]);
-
-               if (!gclass->inst->is_open)
-                       gclass->inst->is_open = mono_class_is_open_constructed_type (t);
-               if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
-
-               gclass->inst->type_argv [i] = t;
-       }
-
-       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
-       gclass->container_class = klass;
-
-       if (klass->generic_class) {
-               MonoGenericClass *kgclass = klass->generic_class;
-               MonoGenericClass *ogclass = gclass;
-
-               gclass = g_new0 (MonoGenericClass, 1);
-
-               gclass->inst = g_new0 (MonoGenericInst, 1);
-               gclass->inst->type_argc = kgclass->inst->type_argc;
-               gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
-               gclass->inst->is_reference = 1;
-
-               for (i = 0; i < gclass->inst->type_argc; i++) {
-                       MonoType *t = kgclass->inst->type_argv [i];
-
-                       t = mono_class_inflate_generic_type (t, mono_generic_class_get_context (ogclass));
-
-                       if (!gclass->inst->is_open)
-                               gclass->inst->is_open = mono_class_is_open_constructed_type (t);
-                       if (gclass->inst->is_reference)
-                               gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
-
-                       gclass->inst->type_argv [i] = t;
-               }
-
-               gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
-               gclass->container_class = kgclass->container_class;
-       }
-
-       geninst = g_new0 (MonoType, 1);
-       geninst->type = MONO_TYPE_GENERICINST;
-
-       cached = mono_metadata_lookup_generic_class (gclass);
-       if (cached) {
-               g_free (gclass);
-               mono_loader_unlock ();
-               geninst->data.generic_class = cached;
-               return geninst;
-       }
-
-       geninst->data.generic_class = gclass;
+       MonoGenericClass *gclass;
+       MonoGenericInst *inst;
 
-       mono_loader_unlock ();
+       g_assert (klass->generic_container);
 
-       return geninst;
-}
+       inst = mono_metadata_get_generic_inst (type_argc, types);
+       gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
 
-static inline MonoType*
-dup_type (const MonoType *original)
-{
-       MonoType *r = g_new0 (MonoType, 1);
-       *r = *original;
-       r->attrs = original->attrs;
-       r->byref = original->byref;
-       if (original->type == MONO_TYPE_PTR)
-               r->data.type = dup_type (original->data.type);
-       else if (original->type == MONO_TYPE_ARRAY)
-               r->data.array = mono_dup_array_type (original->data.array);
-       else if (original->type == MONO_TYPE_FNPTR)
-               r->data.method = mono_metadata_signature_deep_dup (original->data.method);
-       mono_stats.generics_metadata_size += sizeof (MonoType);
-       return r;
+       return mono_generic_class_get_class (gclass);
 }
 
 MonoReflectionMethod*
 mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
 {
+       MonoClass *klass;
        MonoMethod *method, *inflated;
+       MonoMethodInflated *imethod;
        MonoReflectionMethodBuilder *mb = NULL;
-       MonoGenericContainer *container;
-       MonoGenericMethod *gmethod;
-       MonoGenericContext *context;
+       MonoGenericContext tmp_context;
        MonoGenericInst *ginst;
+       MonoType **type_argv;
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
@@ -8885,60 +8816,31 @@ 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))
                return NULL;
 
-       container = method->generic_container;
-       g_assert (container);
-
-       if (!container->method_hash)
-               container->method_hash = g_hash_table_new (
-                       (GHashFunc) mono_metadata_generic_method_hash,
-                       (GCompareFunc) mono_metadata_generic_method_equal);
-
-       ginst = g_new0 (MonoGenericInst,1 );
-       ginst->type_argc = count;
-       ginst->type_argv = g_new0 (MonoType *, count);
-       ginst->is_reference = 1;
+       type_argv = g_new0 (MonoType *, count);
        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]);
+               type_argv [i] = garg->type;
        }
-       ginst = mono_metadata_lookup_generic_inst (ginst);
+       ginst = mono_metadata_get_generic_inst (count, type_argv);
+       g_free (type_argv);
 
-       gmethod = g_new0 (MonoGenericMethod, 1);
-       if (method->klass->generic_class)
-               gmethod->class_inst = method->klass->generic_class->inst;
-       gmethod->container = container;
-       gmethod->inst = ginst;
+       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, gmethod);
-       if (inflated) {
-               g_free (gmethod);
-
-               return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
-       }
-
-       MOVING_GC_REGISTER (&gmethod->reflection_info);
-       gmethod->reflection_info = rmethod;
-
-       context = g_new0 (MonoGenericContext, 1);
-       context->class_inst = gmethod->class_inst;
-       context->gmethod = gmethod;
-
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
+       inflated = mono_class_inflate_generic_method (method, &tmp_context);
+       imethod = (MonoMethodInflated *) inflated;
 
-       inflated = mono_class_inflate_generic_method (method, context);
-       g_hash_table_insert (container->method_hash, gmethod, inflated);
+       MOVING_GC_REGISTER (&imethod->reflection_info);
+       imethod->reflection_info = rmethod;
 
        return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
@@ -8946,7 +8848,8 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
 static MonoMethod *
 inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
 {
-       MonoGenericMethod *gmethod = NULL;
+       MonoMethodInflated *imethod;
+       MonoGenericContext tmp_context;
        MonoGenericContext *context;
        MonoClass *klass;
 
@@ -8957,19 +8860,17 @@ inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoO
        if (method->generic_container) {
                g_assert (method->klass == klass->generic_class->container_class);
 
-               gmethod = g_new0 (MonoGenericMethod, 1);
-               gmethod->class_inst = klass->generic_class->inst;
-               gmethod->container = method->generic_container;
-               MOVING_GC_REGISTER (&gmethod->reflection_info);
-               gmethod->reflection_info = obj;
-               gmethod->inst = method->generic_container->context.gmethod->inst;
-
-               context = g_new0 (MonoGenericContext, 1);
-               context->class_inst = klass->generic_class->inst;
-               context->gmethod = gmethod;
+               tmp_context.class_inst = klass->generic_class->context.class_inst;
+               tmp_context.method_inst = method->generic_container->context.method_inst;
+               context = &tmp_context;
        }
 
-       return mono_class_inflate_generic_method_full (method, klass, context);
+       imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context);
+       if (method->generic_container) {
+               MOVING_GC_REGISTER (&imethod->reflection_info);
+               imethod->reflection_info = obj;
+       }
+       return (MonoMethod *) imethod;
 }
 
 static MonoMethod *
@@ -9448,11 +9349,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);
 
@@ -9626,6 +9532,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:
  *
@@ -9804,12 +9720,17 @@ const static guint32 declsec_flags_map[] = {
 static guint32
 mono_declsec_get_flags (MonoImage *image, guint32 token)
 {
-       guint32 index = mono_metadata_declsec_from_index (image, token);
+       int index = mono_metadata_declsec_from_index (image, token);
        MonoTableInfo *t = &image->tables [MONO_TABLE_DECLSECURITY];
        guint32 result = 0;
        guint32 action;
        int i;
 
+       /* HasSecurity can be present for other, not specially encoded, attributes,
+          e.g. SuppressUnmanagedCodeSecurityAttribute */
+       if (index < 0)
+               return 0;
+
        for (i = index; i < t->rows; i++) {
                guint32 cols [MONO_DECL_SECURITY_SIZE];