Make code behaving like .Net.
[mono.git] / mono / metadata / reflection.c
index f75772f1ad9e5778d967608590075eff8d714286..664d6f90b55ed11c6900823e2ecd97f467f1802c 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
  *
  */
 #include <config.h>
 #include <mono/utils/mono-string.h>
 #include <mono/utils/mono-error-internals.h>
 
-
-#if HAVE_SGEN_GC
-static void* reflection_info_desc = NULL;
-#define MOVING_GC_REGISTER(addr) do {  \
-               if (!reflection_info_desc) {    \
-                       gsize bmap = 1;         \
-                       reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);       \
-               }       \
-               mono_gc_register_root ((char*)(addr), sizeof (gpointer), reflection_info_desc); \
-       } while (0)
-#else
-#define MOVING_GC_REGISTER(addr)
-#endif
-
 static gboolean is_usertype (MonoReflectionType *ref);
 static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
 
@@ -1176,7 +1163,9 @@ lookup_custom_attr (MonoImage *image, gpointer member)
        if (!res)
                return NULL;
 
-       return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+       res = g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+       res->cached = 0;
+       return res;
 }
 
 static gboolean
@@ -2204,7 +2193,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        entry = g_new0 (GenericParamTableEntry, 1);
        entry->owner = owner;
        /* FIXME: track where gen_params should be freed and remove the GC root as well */
-       MOVING_GC_REGISTER (&entry->gparam);
+       MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam);
        entry->gparam = gparam;
        
        g_ptr_array_add (assembly->gen_params, entry);
@@ -2681,11 +2670,13 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
        if (token)
                return token;
 
-       g_assert (tb->generic_params);
-
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
 
-       parent = create_generic_typespec (assembly, tb);
+       if (tb->generic_params)
+               parent = create_generic_typespec (assembly, tb);
+       else
+               parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb));
+       
        name = mono_string_to_utf8 (rmb.name);
        sig = method_builder_encode_signature (assembly, &rmb);
 
@@ -2755,7 +2746,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl
                if (is_field_on_inst (field))
                        type = get_field_on_inst_generic_type (field);
                else
-                       type = field->type;
+                       type = mono_field_get_type (field);
        }
        token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
                                                                                        mono_field_get_name (field),
@@ -2870,6 +2861,8 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI
        MonoMethod *method, *inflated;
        int count, i;
 
+       init_type_builder_generics ((MonoObject*)m->inst);
+
        method = inflate_method (m->inst, (MonoObject*)m->mb);
 
        klass = method->klass;
@@ -4333,7 +4326,7 @@ fixup_cattrs (MonoDynamicImage *assembly)
                        ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
                        g_assert (ctor);
 
-                       if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+                       if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")|| !strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
                                MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
                                idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
                                values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
@@ -4937,7 +4930,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                if (tb->generic_params) {
                        token = mono_image_get_generic_field_token (assembly, fb);
                } else {
-                       if ((tb->module->dynamic_image == assembly)) {
+                       if (tb->module->dynamic_image == assembly) {
                                token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
                        } else {
                                token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
@@ -4951,15 +4944,16 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                        type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                        token = mono_image_typedef_or_ref_full (assembly, type, TRUE);
                        token = mono_metadata_token_from_dor (token);
-               } else {
+               } else if (tb->module->dynamic_image == assembly) {
                        token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+               } else {
+                       MonoType *type;
+                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+                       token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
                }
        } else if (strcmp (klass->name, "MonoType") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                MonoClass *mc = mono_class_from_mono_type (type);
-               if (!mono_class_init (mc))
-                       mono_raise_exception (mono_class_get_exception_for_failure (mc));
-
                token = mono_metadata_token_from_dor (
                        mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
        } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
@@ -5192,11 +5186,6 @@ mono_dynamic_image_free (MonoDynamicImage *image)
        if (di->gen_params) {
                for (i = 0; i < di->gen_params->len; i++) {
                        GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
-                       if (entry->gparam->type.type) {
-                               MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
-                               g_free ((char*)mono_generic_param_info (param)->name);
-                               g_free (param);
-                       }
                        mono_gc_deregister_root ((char*) &entry->gparam);
                        g_free (entry);
                }
@@ -6322,104 +6311,6 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        return res;
 }
 
-static gboolean
-mymono_metadata_type_equal (MonoType *t1, MonoType *t2)
-{
-       if ((t1->type != t2->type) ||
-           (t1->byref != t2->byref))
-               return FALSE;
-
-       switch (t1->type) {
-       case MONO_TYPE_VOID:
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I8:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_R4:
-       case MONO_TYPE_R8:
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U:
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_TYPEDBYREF:
-               return TRUE;
-       case MONO_TYPE_VALUETYPE:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-               return t1->data.klass == t2->data.klass;
-       case MONO_TYPE_PTR:
-               return mymono_metadata_type_equal (t1->data.type, t2->data.type);
-       case MONO_TYPE_ARRAY:
-               if (t1->data.array->rank != t2->data.array->rank)
-                       return FALSE;
-               return t1->data.array->eklass == t2->data.array->eklass;
-       case MONO_TYPE_GENERICINST: {
-               int i;
-               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;
-               /* 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;
-       }
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               return t1->data.generic_param == t2->data.generic_param;
-       default:
-               g_error ("implement type compare for %0x!", t1->type);
-               return FALSE;
-       }
-
-       return FALSE;
-}
-
-static guint
-mymono_metadata_type_hash (MonoType *t1)
-{
-       guint hash;
-
-       hash = t1->type;
-
-       hash |= t1->byref << 6; /* do not collide with t1->type values */
-       switch (t1->type) {
-       case MONO_TYPE_VALUETYPE:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-               /* check if the distribution is good enough */
-               return ((hash << 5) - hash) ^ mono_aligned_addr_hash (t1->data.klass);
-       case MONO_TYPE_PTR:
-               return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
-       case MONO_TYPE_GENERICINST: {
-               int i;
-               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) {
-                       hash += mymono_metadata_type_hash (inst->type_argv [i]);
-                       hash *= 13;
-               }
-               return hash;
-       }
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               return ((hash << 5) - hash) ^ GPOINTER_TO_UINT (t1->data.generic_param);
-       }
-       return hash;
-}
-
 static gboolean
 verify_safe_for_managed_space (MonoType *type)
 {
@@ -6533,8 +6424,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
        mono_domain_lock (domain);
        if (!domain->type_hash)
-               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
-                               (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                               (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
        if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
                mono_domain_unlock (domain);
                mono_loader_unlock ();
@@ -6595,11 +6486,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                        return mono_class_get_ref_info (klass);
                }
        }
-#ifdef HAVE_SGEN_GC
-       res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class));
-#else
-       res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
-#endif
+       /* This is stored in vtables/JITted code so it has to be pinned */
+       res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.monotype_class);
        res->type = type;
        mono_g_hash_table_insert (domain->type_hash, type, res);
 
@@ -6980,6 +6868,10 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        unsigned char format, flags;
        int i;
 
+       /* for compatibility with .net */
+    if (method->dynamic)
+        mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+
        if (!System_Reflection_MethodBody)
                System_Reflection_MethodBody = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MethodBody");
        if (!System_Reflection_LocalVariableInfo)
@@ -7973,12 +7865,16 @@ 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);
+                       if (etype == 0x50) {
+                               tklass = mono_defaults.systemtype_class;
+                       } else {
+                               if (etype == 0x51)
+                                       /* See Partition II, Appendix B3 */
+                                       etype = MONO_TYPE_OBJECT;
+                               simple_type.type = etype;
+                               tklass = mono_class_from_mono_type (&simple_type);
+                       }
                        goto handle_enum;
                } else if (subt == 0x55) {
                        char *n;
@@ -8002,7 +7898,7 @@ handle_type:
                val = load_cattr_value (image, &subc->byval_arg, p, end);
                obj = mono_object_new (mono_domain_get (), subc);
                g_assert (!subc->has_references);
-               memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
+               mono_gc_memmove ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
                g_free (val);
                return obj;
        }
@@ -8204,7 +8100,7 @@ find_event_index (MonoClass *klass, MonoEvent *event) {
 }
 
 static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
 {
        const char *p = (const char*)data;
        const char *named;
@@ -8214,10 +8110,14 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
        void **params;
        MonoMethodSignature *sig;
 
+       mono_error_init (error);
+
        mono_class_init (method->klass);
 
-       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
+               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
                return NULL;
+       }
 
        if (len == 0) {
                attr = mono_object_new (mono_domain_get (), method->klass);
@@ -8500,43 +8400,32 @@ create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr)
        return attr;
 }
 
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
-{
-       MonoArray *result;
-       MonoObject *attr;
-       int i;
-
-       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
-       for (i = 0; i < cinfo->num_attrs; ++i) {
-               if (!cinfo->attrs [i].ctor)
-                       /* The cattr type is not finished yet */
-                       /* We should include the type name but cinfo doesn't contain it */
-                       mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
-               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);
-       }
-       return result;
-}
-
 static MonoArray*
-mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass, MonoError *error)
 {
        MonoArray *result;
        MonoObject *attr;
        int i, n;
 
+       mono_error_init (error);
+
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
-               if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
+               if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
                        n ++;
        }
 
        result = mono_array_new_cached (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)) {
-                       attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+               if (!cinfo->attrs [i].ctor)
+                       /* The cattr type is not finished yet */
+                       /* We should include the type name but cinfo doesn't contain it */
+                       mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+               if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
+                       attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size, error);
+                       if (!mono_error_ok (error))
+                               return result;
                        mono_array_setref (result, n, attr);
                        n ++;
                }
@@ -8544,6 +8433,14 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
        return result;
 }
 
+MonoArray*
+mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+{
+       MonoError error;
+
+       return mono_custom_attrs_construct_by_type (cinfo, NULL, &error);
+}
+
 static MonoArray*
 mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
 {
@@ -8974,17 +8871,16 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
  * occurs.
  */
 MonoArray*
-mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
 {
        MonoArray *result;
        MonoCustomAttrInfo *cinfo;
 
+       mono_error_init (error);
+
        cinfo = mono_reflection_get_custom_attrs_info (obj);
        if (cinfo) {
-               if (attr_klass)
-                       result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
-               else
-                       result = mono_custom_attrs_construct (cinfo);
+               result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
        } else {
@@ -9007,7 +8903,9 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
 MonoArray*
 mono_reflection_get_custom_attrs (MonoObject *obj)
 {
-       return mono_reflection_get_custom_attrs_by_type (obj, NULL);
+       MonoError error;
+
+       return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
 }
 
 /*
@@ -9227,8 +9125,8 @@ mono_reflection_register_with_runtime (MonoReflectionType *type)
                mono_class_setup_supertypes (class);
        } else {
                if (!domain->type_hash)
-                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
-                                       (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                                       (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
                mono_g_hash_table_insert (domain->type_hash, res, type);
        }
        mono_domain_unlock (domain);
@@ -10172,8 +10070,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        m->slot = -1;
        m->flags = rmb->attrs;
        m->iflags = rmb->iattrs;
-       m->name = mono_string_to_utf8_image (image, rmb->name, &error);
-       g_assert (mono_error_ok (&error));
+       m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
        m->klass = klass;
        m->signature = sig;
        m->sre_method = TRUE;
@@ -10446,10 +10343,12 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
 {
        MonoClassField *field;
        MonoType *custom;
+       MonoError error;
 
        field = g_new0 (MonoClassField, 1);
 
-       field->name = mono_string_to_utf8 (fb->name);
+       field->name = mono_string_to_utf8_image (klass->image, fb->name, &error);
+       g_assert (mono_error_ok (&error));
        if (fb->attrs || fb->modreq || fb->modopt) {
                field->type = mono_metadata_type_dup (NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
                field->type->attrs = fb->attrs;
@@ -10457,7 +10356,8 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
                g_assert (klass->image->dynamic);
                custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt);
                g_free (field->type);
-               field->type = custom;
+               field->type = mono_metadata_type_dup (klass->image, custom);
+               g_free (custom);
        } else {
                field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
        }
@@ -10603,6 +10503,9 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
                mono_loader_unlock ();
        }
+
+       if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
+               mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
        
        return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
@@ -10716,27 +10619,11 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        gklass = gclass->container_class;
        mono_class_init (gklass);
 
-       dgclass->count_methods = methods ? mono_array_length (methods) : 0;
-       dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
        dgclass->count_fields = fields ? mono_array_length (fields) : 0;
 
-       dgclass->methods = g_new0 (MonoMethod *, dgclass->count_methods);
-       dgclass->ctors = g_new0 (MonoMethod *, dgclass->count_ctors);
-       dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields);
-       dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
-       dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
-
-       for (i = 0; i < dgclass->count_methods; i++) {
-               MonoObject *obj = mono_array_get (methods, gpointer, i);
-
-               dgclass->methods [i] = inflate_method ((MonoReflectionType*)type, obj);
-       }
-
-       for (i = 0; i < dgclass->count_ctors; i++) {
-               MonoObject *obj = mono_array_get (ctors, gpointer, i);
-
-               dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
-       }
+       dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields);
+       dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields);
+       dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
 
        for (i = 0; i < dgclass->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
@@ -10756,19 +10643,36 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                dgclass->fields [i].type = mono_class_inflate_generic_type (
                        field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
                dgclass->field_generic_types [i] = field->type;
-               MOVING_GC_REGISTER (&dgclass->field_objects [i]);
+               MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
                dgclass->field_objects [i] = obj;
 
                if (inflated_field) {
                        g_free (inflated_field);
                } else {
-                       dgclass->fields [i].name = g_strdup (dgclass->fields [i].name);
+                       dgclass->fields [i].name = mono_image_set_strdup (gclass->owner, dgclass->fields [i].name);
                }
        }
 
        dgclass->initialized = TRUE;
 }
 
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+       MonoDynamicGenericClass *dgclass;
+       int i;
+
+       g_assert (gclass->is_dynamic);
+
+       dgclass = (MonoDynamicGenericClass *)gclass;
+
+       for (i = 0; i < dgclass->count_fields; ++i) {
+               MonoClassField *field = dgclass->fields + i;
+               mono_metadata_free_type (field->type);
+               MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
+       }
+}
+
 static void
 fix_partial_generic_class (MonoClass *klass)
 {
@@ -11046,6 +10950,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        klass->size_inited = 1;
 
        for (i = 0; i < klass->field.count; ++i) {
+               MonoArray *rva_data;
                fb = mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
                field->name = mono_string_to_utf8_image (image, fb->name, error);
@@ -11057,8 +10962,14 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                } else {
                        field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
                }
-               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-                       klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
+
+               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
+                       char *base = mono_array_addr (rva_data, char, 0);
+                       size_t size = mono_array_length (rva_data);
+                       char *data = mono_image_alloc (klass->image, size);
+                       memcpy (data, base, size);
+                       klass->ext->field_def_values [i].data = data;
+               }
                if (fb->offset != -1)
                        field->offset = fb->offset;
                field->parent = klass;
@@ -11328,6 +11239,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        klass->flags = tb->attrs;
        klass->has_cctor = 1;
        klass->has_finalize = 1;
+       klass->has_finalize_inited = 1;
 
        /* fool mono_class_setup_parent */
        klass->supertypes = NULL;
@@ -11428,10 +11340,17 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
        MonoGenericParamFull *param;
        MonoImage *image;
        MonoClass *pklass;
+       MonoError error;
 
        MONO_ARCH_SAVE_REGS;
 
-       param = g_new0 (MonoGenericParamFull, 1);
+       image = &gparam->tbuilder->module->dynamic_image->image;
+
+       param = mono_image_new0 (image, MonoGenericParamFull, 1);
+
+       param->info.name = mono_string_to_utf8_image (image, gparam->name, &error);
+       g_assert (mono_error_ok (&error));
+       param->param.num = gparam->index;
 
        if (gparam->mbuilder) {
                if (!gparam->mbuilder->generic_container) {
@@ -11455,10 +11374,6 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
                param->param.owner = gparam->tbuilder->generic_container;
        }
 
-       param->info.name = mono_string_to_utf8 (gparam->name);
-       param->param.num = gparam->index;
-
-       image = &gparam->tbuilder->module->dynamic_image->image;
        pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);
 
        gparam->type.type = &pklass->byval_arg;
@@ -11527,15 +11442,47 @@ mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
        return result;
 }
 
+typedef struct {
+       MonoMethod *handle;
+       MonoDomain *domain;
+} DynamicMethodReleaseData;
+
+/*
+ * The runtime automatically clean up those after finalization.
+*/     
+static MonoReferenceQueue *dynamic_method_queue;
+
+static void
+free_dynamic_method (void *dynamic_method)
+{
+       DynamicMethodReleaseData *data = dynamic_method;
+
+       mono_runtime_free_method (data->domain, data->handle);
+       g_free (data);
+}
+
 void 
 mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 {
+       MonoReferenceQueue *queue;
+       MonoMethod *handle;
+       DynamicMethodReleaseData *release_data;
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
        MonoClass *klass;
        GSList *l;
        int i;
 
+       if (mono_runtime_is_shutting_down ())
+               mono_raise_exception (mono_get_exception_invalid_operation (""));
+
+       if (!(queue = dynamic_method_queue)) {
+               mono_loader_lock ();
+               if (!(queue = dynamic_method_queue))
+                       queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
+               mono_loader_unlock ();
+       }
+
        sig = dynamic_method_to_signature (mb);
 
        reflection_methodbuilder_from_dynamic_method (&rmb, mb);
@@ -11593,7 +11540,12 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 
        klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class;
 
-       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+       mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+       release_data = g_new (DynamicMethodReleaseData, 1);
+       release_data->handle = handle;
+       release_data->domain = mono_object_get_domain ((MonoObject*)mb);
+       if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
+               g_free (release_data);
 
        /* Fix up refs entries pointing at us */
        for (l = mb->referenced_by; l; l = l->next) {
@@ -11619,16 +11571,6 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 
 #endif /* DISABLE_REFLECTION_EMIT */
 
-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_is_valid_dynamic_token:
@@ -12147,6 +12089,12 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
        return ref->type;
 }
 
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+       g_assert_not_reached ();
+}
+
 #endif /* DISABLE_REFLECTION_EMIT */
 
 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
@@ -12606,3 +12554,18 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass)
        else
                return *(MonoBoolean*)mono_object_unbox (res);
 }
+
+/**
+ * mono_reflection_type_get_type:
+ * @reftype: the System.Type object
+ *
+ * Returns the MonoType* associated with the C# System.Type object @reftype.
+ */
+MonoType*
+mono_reflection_type_get_type (MonoReflectionType *reftype)
+{
+       g_assert (reftype);
+
+       return mono_reflection_type_get_handle (reftype);
+}
+