Merge pull request #487 from mayerwin/patch-1
[mono.git] / mono / metadata / reflection.c
index e7169d28c5cd01296c7338e45ccc8f3161e4e0e1..0c3d2364822f6823828307a9b66db80e72c149dd 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
@@ -1301,6 +1290,11 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo
                switch (mono_metadata_token_table (token)) {
                case MONO_TABLE_METHOD:
                        type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       /*
+                        * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
+                        * method, not the one returned by mono_image_create_token ().
+                        */
+                       mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
                        break;
                case MONO_TABLE_MEMBERREF:
                        type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
@@ -1554,29 +1548,35 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild
        MonoDynamicTable *table;
        guint32 *values;
        guint32 tok;
+       MonoReflectionMethod *m;
+       int i;
 
-       if (!mb->override_method)
+       if (!mb->override_methods)
                return;
 
-       table = &assembly->tables [MONO_TABLE_METHODIMPL];
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + table->rows * MONO_METHODIMPL_SIZE;
-       values [MONO_METHODIMPL_CLASS] = tb->table_idx;
-       values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+       for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
+               m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
 
-       tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE, FALSE);
-       switch (mono_metadata_token_table (tok)) {
-       case MONO_TABLE_MEMBERREF:
-               tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
-               break;
-       case MONO_TABLE_METHOD:
-               tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
-               break;
-       default:
-               g_assert_not_reached ();
+               table = &assembly->tables [MONO_TABLE_METHODIMPL];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_METHODIMPL_SIZE;
+               values [MONO_METHODIMPL_CLASS] = tb->table_idx;
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+               tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE);
+               switch (mono_metadata_token_table (tok)) {
+               case MONO_TABLE_MEMBERREF:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+                       break;
+               case MONO_TABLE_METHOD:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               values [MONO_METHODIMPL_DECLARATION] = tok;
        }
-       values [MONO_METHODIMPL_DECLARATION] = tok;
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -2204,7 +2204,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 +2681,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 +2757,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),
@@ -4332,13 +4334,17 @@ fixup_cattrs (MonoDynamicImage *assembly)
                if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
                        idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
                        token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
-                       ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+                       ctor = mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
                        g_assert (ctor);
 
                        if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
                                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;
+                       } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
+                               MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
+                               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;
                        }
                }
        }
@@ -4939,7 +4945,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);
@@ -4953,15 +4959,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) {
@@ -5117,6 +5124,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
        image->gen_params = g_ptr_array_new ();
+       image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
 
        /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/
        string_heap_init (&image->sheap);
@@ -5157,6 +5165,26 @@ free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
        g_free (key);
 }
 
+static void
+release_hashtable (MonoGHashTable **hash)
+{
+       if (*hash) {
+               mono_g_hash_table_destroy (*hash);
+               *hash = NULL;
+       }
+}
+
+void
+mono_dynamic_image_release_gc_roots (MonoDynamicImage *image)
+{
+       release_hashtable (&image->token_fixups);
+       release_hashtable (&image->handleref_managed);
+       release_hashtable (&image->tokens);
+       release_hashtable (&image->remapped_tokens);
+       release_hashtable (&image->generic_def_objects);
+       release_hashtable (&image->methodspec);
+}
+
 void
 mono_dynamic_image_free (MonoDynamicImage *image)
 {
@@ -5176,6 +5204,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                mono_g_hash_table_destroy (di->handleref_managed);
        if (di->tokens)
                mono_g_hash_table_destroy (di->tokens);
+       if (di->remapped_tokens)
+               mono_g_hash_table_destroy (di->remapped_tokens);
        if (di->generic_def_objects)
                mono_g_hash_table_destroy (di->generic_def_objects);
        if (di->blob_cache) {
@@ -5194,11 +5224,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);
                }
@@ -6324,104 +6349,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)
 {
@@ -6535,8 +6462,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 ();
@@ -6597,11 +6524,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);
 
@@ -6938,7 +6862,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
                }
 
                if (mspecs [i + 1])
-                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
+                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
                
                mono_array_setref (res, i, param);
        }
@@ -6982,6 +6906,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)
@@ -7975,12 +7903,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;
@@ -8004,7 +7936,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;
        }
@@ -9231,8 +9163,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);
@@ -10087,45 +10019,46 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
 }
 #endif /* !DISABLE_REFLECTION_EMIT */
 
-MonoReflectionMarshal*
-mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
+MonoReflectionMarshalAsAttribute*
+mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
                                                                                   MonoMarshalSpec *spec)
 {
-       static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass;
-       MonoReflectionMarshal *minfo;
+       static MonoClass *System_Reflection_Emit_MarshalAsAttribute;
+       MonoReflectionMarshalAsAttribute *minfo;
        MonoType *mtype;
 
-       if (!System_Reflection_Emit_UnmanagedMarshalClass) {
-               System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name (
-                  mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal");
-               g_assert (System_Reflection_Emit_UnmanagedMarshalClass);
+       if (!System_Reflection_Emit_MarshalAsAttribute) {
+               System_Reflection_Emit_MarshalAsAttribute = mono_class_from_name (
+                  mono_defaults.corlib, "System.Runtime.InteropServices", "MarshalAsAttribute");
+               g_assert (System_Reflection_Emit_MarshalAsAttribute);
        }
 
-       minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass);
-       minfo->type = spec->native;
+       minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new (domain, System_Reflection_Emit_MarshalAsAttribute);
+       minfo->utype = spec->native;
 
-       switch (minfo->type) {
+       switch (minfo->utype) {
        case MONO_NATIVE_LPARRAY:
-               minfo->eltype = spec->data.array_data.elem_type;
-               minfo->count = spec->data.array_data.num_elem;
-               minfo->param_num = spec->data.array_data.param_num;
+               minfo->array_subtype = spec->data.array_data.elem_type;
+               minfo->size_const = spec->data.array_data.num_elem;
+               if (spec->data.array_data.param_num != -1)
+                       minfo->size_param_index = spec->data.array_data.param_num;
                break;
 
        case MONO_NATIVE_BYVALTSTR:
        case MONO_NATIVE_BYVALARRAY:
-               minfo->count = spec->data.array_data.num_elem;
+               minfo->size_const = spec->data.array_data.num_elem;
                break;
 
        case MONO_NATIVE_CUSTOM:
                if (spec->data.custom_data.custom_name) {
                        mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
                        if (mtype)
-                               MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
+                               MONO_OBJECT_SETREF (minfo, marshal_type_ref, mono_type_get_object (domain, mtype));
 
-                       MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
+                       MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
                }
                if (spec->data.custom_data.cookie)
-                       MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
+                       MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
                break;
 
        default:
@@ -10176,8 +10109,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;
@@ -10450,10 +10382,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;
@@ -10461,7 +10395,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);
        }
@@ -10695,9 +10630,7 @@ inflate_method (MonoReflectionType *type, MonoObject *obj)
 
 /*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
 void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
-                                         MonoArray *ctors, MonoArray *fields, MonoArray *properties,
-                                         MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
 {
        MonoGenericClass *gclass;
        MonoDynamicGenericClass *dgclass;
@@ -10723,28 +10656,12 @@ 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 = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_methods);
-       dgclass->ctors = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_ctors);
        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_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);
-       }
-
        for (i = 0; i < dgclass->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
                MonoClassField *field, *inflated_field = NULL;
@@ -10763,7 +10680,7 @@ 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) {
@@ -10789,9 +10706,7 @@ mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
        for (i = 0; i < dgclass->count_fields; ++i) {
                MonoClassField *field = dgclass->fields + i;
                mono_metadata_free_type (field->type);
-#if HAVE_SGEN_GC
-               MONO_GC_UNREGISTER_ROOT (dgclass->field_objects [i]);
-#endif
+               MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
        }
 }
 
@@ -10987,7 +10902,8 @@ void
 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
 {
        MonoReflectionTypeBuilder *tb;
-       int i, onum;
+       int i, j, onum;
+       MonoReflectionMethod *m;
 
        *overrides = NULL;
        *num_overrides = 0;
@@ -11006,8 +10922,8 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_method)
-                               onum ++;
+                       if (mb->override_methods)
+                               onum += mono_array_length (mb->override_methods);
                }
        }
 
@@ -11018,13 +10934,17 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_method) {
-                               (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
-                               (*overrides) [onum * 2 + 1] = mb->mhandle;
+                       if (mb->override_methods) {
+                               for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
+                                       m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
+
+                                       (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m);
+                                       (*overrides) [onum * 2 + 1] = mb->mhandle;
 
-                               g_assert (mb->mhandle);
+                                       g_assert (mb->mhandle);
 
-                               onum ++;
+                                       onum ++;
+                               }
                        }
                }
        }
@@ -11049,7 +10969,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        mono_error_init (error);
 
        if (tb->class_size) {
-               g_assert ((tb->packing_size & 0xfffffff0) == 0);
+               if ((tb->packing_size & 0xfffffff0) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size);
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+                       return;
+               }
                klass->packing_size = tb->packing_size;
                real_size = klass->instance_size + tb->class_size;
        }
@@ -11072,6 +10996,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);
@@ -11083,8 +11008,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;
@@ -11354,6 +11285,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;
@@ -11454,10 +11386,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) {
@@ -11481,10 +11420,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;
@@ -11553,15 +11488,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);
@@ -11619,7 +11586,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) {
@@ -11645,16 +11617,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:
@@ -12011,7 +11973,14 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                                is_sre_pointer (mono_object_get_class(obj))) {
                MonoReflectionType *ref_type = (MonoReflectionType *)obj;
                MonoType *type = mono_reflection_type_get_handle (ref_type);
-               result = mono_class_from_mono_type (type);
+
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type (type, context);
+                       result = mono_class_from_mono_type (inflated);
+                       mono_metadata_free_type (inflated);
+               } else {
+                       result = mono_class_from_mono_type (type);
+               }
                *handle_class = mono_defaults.typehandle_class;
        } else {
                g_print ("%s\n", obj->vtable->klass->name);
@@ -12106,9 +12075,7 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject
 }
 
 void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
-                                         MonoArray *ctors, MonoArray *fields, MonoArray *properties,
-                                         MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
 {
        g_assert_not_reached ();
 }
@@ -12638,3 +12605,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);
+}
+