Don't assert on broken DM names.
[mono.git] / mono / metadata / reflection.c
index 9ebeeb848238daa9c7f239286c1ecea1765bfff7..bd03a87baa03a4e48c0a3b66ebaad6c5d9936617 100644 (file)
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/verify-internals.h>
+#include <mono/metadata/mono-ptr-array.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);
 
@@ -157,7 +145,7 @@ const unsigned char table_sizes [MONO_TABLE_NUM] = {
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
-static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance);
 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
 static void    ensure_runtime_vtable (MonoClass *klass);
@@ -201,6 +189,9 @@ static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, Mono
 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
 
+static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
+static void init_type_builder_generics (MonoObject *type);
+
 #define RESOLVE_TYPE(type) do { type = (void*)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type); } while (0)
 #define RESOLVE_ARRAY_TYPE_ELEMENT(array, index) do {  \
        MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index);        \
@@ -1171,7 +1162,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
@@ -1711,13 +1704,31 @@ field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *
 {
        SigBuffer buf;
        guint32 idx;
+       guint32 typespec = 0;
+       MonoType *type;
+       MonoClass *class;
+
+       init_type_builder_generics (fb->type);
+
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+       class = mono_class_from_mono_type (type);
 
        sigbuffer_init (&buf, 32);
        
        sigbuffer_add_value (&buf, 0x06);
        encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
        /* encode custom attributes before the type */
-       encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
+
+       if (class->generic_container)
+               typespec = create_typespec (assembly, type);
+
+       if (typespec) {
+               MonoGenericClass *gclass;
+               gclass = mono_metadata_lookup_generic_class (class, class->generic_container->context.class_inst, TRUE);
+               encode_generic_class (assembly, gclass, &buf);
+       } else {
+               encode_type (assembly, type, &buf);
+       }
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
        return idx;
@@ -1778,12 +1789,18 @@ handle_enum:
 #endif
 #endif
                break;
-       case MONO_TYPE_VALUETYPE:
-               if (val->vtable->klass->enumtype) {
-                       *ret_type = mono_class_enum_basetype (val->vtable->klass)->type;
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *klass = val->vtable->klass;
+               
+               if (klass->enumtype) {
+                       *ret_type = mono_class_enum_basetype (klass)->type;
                        goto handle_enum;
-               } else
-                       g_error ("we can't encode valuetypes");
+               } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
+                       len = 8;
+               } else 
+                       g_error ("we can't encode valuetypes, we should have never reached this line");
+               break;
+       }
        case MONO_TYPE_CLASS:
                break;
        case MONO_TYPE_STRING: {
@@ -1981,7 +1998,10 @@ property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBui
        if (!mb && smb && smb->parameters)
                nparams = mono_array_length (smb->parameters) - 1;
        sigbuffer_init (&buf, 32);
-       sigbuffer_add_byte (&buf, 0x08);
+       if (fb->call_conv & 0x20)
+               sigbuffer_add_byte (&buf, 0x28);
+       else
+               sigbuffer_add_byte (&buf, 0x08);
        sigbuffer_add_value (&buf, nparams);
        if (mb) {
                encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
@@ -2172,7 +2192,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);
@@ -2649,11 +2669,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);
 
@@ -2704,29 +2726,29 @@ get_field_on_inst_generic_type (MonoClassField *field)
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
 {
        MonoType *type;
        guint32 token;
-       MonoClassField *field;
+
+       g_assert (field);
+       g_assert (field->parent);
 
        token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
        if (token)
                return token;
-       g_assert (f->field->parent);
 
-       field = f->field;
        if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
                int index = field - field->parent->fields;
                type = field->parent->generic_class->container_class->fields [index].type;
        } else {
-               if (is_field_on_inst (f->field))
-                       type = get_field_on_inst_generic_type (f->field);
+               if (is_field_on_inst (field))
+                       type = get_field_on_inst_generic_type (field);
                else
-                       type = f->field->type;
+                       type = field->type;
        }
-       token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg, 
-                                                                                       mono_field_get_name (f->field),  
+       token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
+                                                                                       mono_field_get_name (field),
                                                                                        fieldref_encode_signature (assembly, field->parent->image, type));
        mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
        return token;
@@ -2838,6 +2860,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;
@@ -3139,12 +3163,25 @@ add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *mod
        return t;
 }
 
+static void
+init_type_builder_generics (MonoObject *type)
+{
+       MonoReflectionTypeBuilder *tb;
+
+       if (!is_sre_type_builder(mono_object_class (type)))
+               return;
+       tb = (MonoReflectionTypeBuilder *)type;
+
+       if (tb && tb->generic_container)
+               mono_reflection_create_generic_class (tb);
+}
+
 static guint32
 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
 {
        MonoDynamicTable *table;
        MonoClass *klass;
-       MonoType *custom = NULL;
+       MonoType *custom = NULL, *type;
        guint32 *values;
        guint32 token, pclass, parent, sig;
        gchar *name;
@@ -3156,15 +3193,17 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        klass = mono_class_from_mono_type (mono_reflection_type_get_handle (fb->typeb));
        name = mono_string_to_utf8 (fb->name);
 
+       /*FIXME this is one more layer of ugliness due how types are created.*/
+       init_type_builder_generics (fb->type);
+
        /* fb->type does not include the custom modifiers */
        /* FIXME: We should do this in one place when a fieldbuilder is created */
-       if (fb->modreq || fb->modopt) {
-               custom = add_custom_modifiers (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type), fb->modreq, fb->modopt);
-               sig = fieldref_encode_signature (assembly, NULL, custom);
-               g_free (custom);
-       } else {
-               sig = fieldref_encode_signature (assembly, NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
-       }
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+       if (fb->modreq || fb->modopt)
+               type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt);
+
+       sig = fieldref_encode_signature (assembly, NULL, type);
+       g_free (custom);
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
        g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
@@ -3501,11 +3540,11 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
 #endif
 
 static void
-collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
+collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
 {
        int i;
 
-       g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
+       mono_ptr_array_append (*types, type);
 
        if (!type->subtypes)
                return;
@@ -4533,7 +4572,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
        MonoDynamicImage *assembly;
        MonoReflectionAssemblyBuilder *assemblyb;
        MonoDomain *domain;
-       GPtrArray *types;
+       MonoPtrArray types;
        guint32 *values;
        int i, j;
 
@@ -4591,34 +4630,34 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
        mono_image_fill_module_table (domain, moduleb, assembly);
 
        /* Collect all types into a list sorted by their table_idx */
-       types = g_ptr_array_new ();
+       mono_ptr_array_init (types, moduleb->num_types);
 
        if (moduleb->types)
                for (i = 0; i < moduleb->num_types; ++i) {
                        MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
-                       collect_types (types, type);
+                       collect_types (&types, type);
                }
 
-       g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx);
+       mono_ptr_array_sort (types, (gpointer)compare_types_by_table_idx);
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       table->rows += types->len;
+       table->rows += mono_ptr_array_size (types);
        alloc_table (table, table->rows);
 
        /*
         * Emit type names + namespaces at one place inside the string heap,
         * so load_class_names () needs to touch fewer pages.
         */
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
                string_heap_insert_mstring (&assembly->sheap, tb->nspace);
        }
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
                string_heap_insert_mstring (&assembly->sheap, tb->name);
        }
 
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
                mono_image_get_type_info (domain, type, assembly);
        }
 
@@ -4652,8 +4691,8 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
                }
        }
 
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
                if (type->methods) {
                        for (j = 0; j < type->num_methods; ++j) {
                                MonoReflectionMethodBuilder *mb = mono_array_get (
@@ -4664,7 +4703,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
                }
        }
 
-       g_ptr_array_free (types, TRUE);
+       mono_ptr_array_destroy (types);
 
        fixup_cattrs (assembly);
 }
@@ -4747,11 +4786,12 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 {
        MonoClass *klass;
        guint32 token = 0;
+       MonoMethodSignature *sig;
 
        klass = obj->vtable->klass;
        if (strcmp (klass->name, "MonoMethod") == 0) {
                MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
-               MonoMethodSignature *sig, *old;
+               MonoMethodSignature *old;
                guint32 sig_token, parent;
                int nargs, i;
 
@@ -4789,13 +4829,37 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
        } else if (strcmp (klass->name, "MethodBuilder") == 0) {
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                ReflectionMethodBuilder rmb;
-               guint32 parent, sig;
+               guint32 parent, sig_token;
+               int nopt_args, nparams, ngparams, i;
                char *name;
 
                reflection_methodbuilder_from_method_builder (&rmb, mb);
                rmb.opt_types = opt_param_types;
+               nopt_args = mono_array_length (opt_param_types);
 
-               sig = method_builder_encode_signature (assembly, &rmb);
+               nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
+               ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
+               sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
+
+               sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
+               sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
+               sig->call_convention = rmb.call_conv;
+               sig->generic_param_count = ngparams;
+               sig->param_count = nparams + nopt_args;
+               sig->sentinelpos = nparams;
+               sig->ret = mono_reflection_type_get_handle (rmb.rtype);
+
+               for (i = 0; i < nparams; i++) {
+                       MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
+                       sig->params [i] = mono_reflection_type_get_handle (rt);
+               }
+
+               for (i = 0; i < nopt_args; i++) {
+                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
+                       sig->params [nparams + i] = mono_reflection_type_get_handle (rt);
+               }
+
+               sig_token = method_builder_encode_signature (assembly, &rmb);
 
                parent = mono_image_create_token (assembly, obj, TRUE, TRUE);
                g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
@@ -4805,12 +4869,14 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 
                name = mono_string_to_utf8 (rmb.name);
                token = mono_image_get_varargs_method_token (
-                       assembly, parent, name, sig);
+                       assembly, parent, name, sig_token);
                g_free (name);
        } else {
                g_error ("requested method token for %s\n", klass->name);
        }
 
+       g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
+       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
        return token;
 }
 
@@ -4827,7 +4893,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
  */
 guint32
 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                                                gboolean create_methodspec, gboolean register_token)
+                                                gboolean create_open_instance, gboolean register_token)
 {
        MonoClass *klass;
        guint32 token = 0;
@@ -4846,7 +4912,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
                        token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
                else
-                       token = mono_image_get_methodbuilder_token (assembly, mb, create_methodspec);
+                       token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance);
                /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
        } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
                MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
@@ -4863,16 +4929,32 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                if (tb->generic_params) {
                        token = mono_image_get_generic_field_token (assembly, fb);
                } else {
-                       token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+                       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);
+                       }
                }
        } else if (strcmp (klass->name, "TypeBuilder") == 0) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
-               token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+               if (create_open_instance && tb->generic_params) {
+                       MonoType *type;
+                       init_type_builder_generics (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 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);
                token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL));
+                       mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
        } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                token = mono_metadata_token_from_dor (
@@ -4887,7 +4969,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                   strcmp (klass->name, "MonoGenericCMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
                if (m->method->is_inflated) {
-                       if (create_methodspec)
+                       if (create_open_instance)
                                token = mono_image_get_methodspec_token (assembly, m->method);
                        else
                                token = mono_image_get_inflated_method_token (assembly, m->method);
@@ -4910,7 +4992,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                                token = MONO_TOKEN_METHOD_DEF | method_table_idx;
                        }
                } else {
-                       token = mono_image_get_methodref_token (assembly, m->method, create_methodspec);
+                       token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
                }
                /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
        } else if (strcmp (klass->name, "MonoField") == 0) {
@@ -4920,7 +5002,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
                } else {
-                       token = mono_image_get_fieldref_token (assembly, f);
+                       token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
                }
                /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
        } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
@@ -4938,10 +5020,10 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                token = mono_image_get_field_on_inst_token (assembly, f);
        } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
                MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
-               token = mono_image_get_ctor_on_inst_token (assembly, c, create_methodspec);
+               token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance);
        } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
                MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
-               token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec);
+               token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance);
        } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
                MonoReflectionType *type = (MonoReflectionType *)obj;
                token = mono_metadata_token_from_dor (
@@ -4989,6 +5071,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
                version = mono_get_runtime_info ()->runtime_version;
 
 #if HAVE_BOEHM_GC
+       /* The MonoGHashTable's need GC tracking */
        image = GC_MALLOC (sizeof (MonoDynamicImage));
 #else
        image = g_new0 (MonoDynamicImage, 1);
@@ -5015,6 +5098,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->method_to_table_idx = g_hash_table_new (NULL, NULL);
        image->field_to_table_idx = g_hash_table_new (NULL, NULL);
        image->method_aux_hash = g_hash_table_new (NULL, NULL);
+       image->vararg_aux_hash = g_hash_table_new (NULL, NULL);
        image->handleref = g_hash_table_new (NULL, NULL);
        image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
        image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
@@ -5101,11 +5185,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);
                }
@@ -5119,6 +5198,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                g_hash_table_destroy (di->field_to_table_idx);
        if (di->method_aux_hash)
                g_hash_table_destroy (di->method_aux_hash);
+       if (di->vararg_aux_hash)
+               g_hash_table_destroy (di->vararg_aux_hash);
        g_free (di->strong_name);
        g_free (di->win32_res);
        if (di->public_key)
@@ -5159,6 +5240,7 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
                return;
 
 #if HAVE_BOEHM_GC
+       /* assembly->assembly.image might be GC allocated */
        assembly = assemblyb->dynamic_assembly = GC_MALLOC (sizeof (MonoDynamicAssembly));
 #else
        assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
@@ -6228,146 +6310,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) ^ g_str_hash (t1->data.klass->name);
-       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;
-       }
-       }
-       return hash;
-}
-
-static MonoReflectionGenericClass*
-mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
-{
-       static MonoClass *System_Reflection_MonoGenericClass;
-       MonoReflectionGenericClass *res;
-       MonoClass *klass, *gklass;
-       MonoGenericInst *ginst;
-       MonoArray *type_args;
-       int i;
-       MonoObject *tb;
-
-       g_assert (0); /*This code path should not be taken anymore, all MGC instantiation must happen in managed code*/
-
-       if (!System_Reflection_MonoGenericClass) {
-               System_Reflection_MonoGenericClass = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
-               g_assert (System_Reflection_MonoGenericClass);
-       }
-
-       klass = mono_class_from_mono_type (geninst);
-       gklass = klass->generic_class->container_class;
-
-       mono_class_init (klass);
-
-#ifdef HAVE_SGEN_GC
-       res = (MonoReflectionGenericClass *) mono_gc_alloc_pinned_obj (mono_class_vtable (domain, System_Reflection_MonoGenericClass), mono_class_instance_size (System_Reflection_MonoGenericClass));
-#else
-       res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
-#endif
-
-       res->type.type = geninst;
-       tb = mono_class_get_ref_info (gklass);
-       g_assert (tb);
-       g_assert (!strcmp (tb->vtable->klass->name, "TypeBuilder"));
-       MONO_OBJECT_SETREF (res, generic_type, tb);
-
-       ginst = klass->generic_class->context.class_inst;
-       type_args = mono_array_new (domain, mono_defaults.systemtype_class, ginst->type_argc);
-       for (i = 0; i < ginst->type_argc; ++i)
-               mono_array_setref (type_args, i, mono_type_get_object (domain, ginst->type_argv [i]));
-       MONO_OBJECT_SETREF (res, type_arguments, type_args);
-
-       return res;
-}
-
 static gboolean
 verify_safe_for_managed_space (MonoType *type)
 {
@@ -6397,6 +6339,49 @@ verify_safe_for_managed_space (MonoType *type)
        return TRUE;
 }
 
+static MonoType*
+mono_type_normalize (MonoType *type)
+{
+       int i;
+       MonoGenericClass *gclass;
+       MonoGenericInst *ginst;
+       MonoClass *gtd;
+       MonoGenericContainer *gcontainer;
+       MonoType **argv = NULL;
+       gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;
+
+       if (type->type != MONO_TYPE_GENERICINST)
+               return type;
+
+       gclass = type->data.generic_class;
+       ginst = gclass->context.class_inst;
+       if (!ginst->is_open)
+               return type;
+
+       gtd = gclass->container_class;
+       gcontainer = gtd->generic_container;
+       argv = g_newa (MonoType*, ginst->type_argc);
+
+       for (i = 0; i < ginst->type_argc; ++i) {
+               MonoType *t = ginst->type_argv [i], *norm;
+               if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
+                       is_denorm_gtd = FALSE;
+               norm = mono_type_normalize (t);
+               argv [i] = norm;
+               if (norm != t)
+                       requires_rebind = TRUE;
+       }
+
+       if (is_denorm_gtd)
+               return type->byref == gtd->byval_arg.byref ? &gtd->byval_arg : &gtd->this_arg;
+
+       if (requires_rebind) {
+               MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
+               return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
+       }
+
+       return type;
+}
 /*
  * mono_type_get_object:
  * @domain: an app domain
@@ -6407,6 +6392,7 @@ verify_safe_for_managed_space (MonoType *type)
 MonoReflectionType*
 mono_type_get_object (MonoDomain *domain, MonoType *type)
 {
+       MonoType *norm_type;
        MonoReflectionType *res;
        MonoClass *klass = mono_class_from_mono_type (type);
 
@@ -6437,22 +6423,34 @@ 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 ();
                return res;
        }
-       /* Create a MonoGenericClass object for instantiations of not finished TypeBuilders */
-       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder) {
-               res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
+
+       /*Types must be normalized so a generic instance of the GTD get's the same inner type.
+        * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
+        * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
+        * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
+        * artifact of how generics are encoded and should be transparent to managed code so we
+        * need to weed out this diference when retrieving managed System.Type objects.
+        */
+       norm_type = mono_type_normalize (type);
+       if (norm_type != type) {
+               res = mono_type_get_object (domain, norm_type);
                mono_g_hash_table_insert (domain->type_hash, type, res);
                mono_domain_unlock (domain);
                mono_loader_unlock ();
                return res;
        }
 
+       /* This MonoGenericClass hack is no longer necessary. Let's leave it here until we finish with the 2-stage type-builder setup.*/
+       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder)
+               g_assert (0);
+
        if (!verify_safe_for_managed_space (type)) {
                mono_domain_unlock (domain);
                mono_loader_unlock ();
@@ -6487,13 +6485,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                        return mono_class_get_ref_info (klass);
                }
        }
-       // FIXME: Get rid of this, do it in the icalls for Type
-       mono_class_init (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);
 
@@ -6615,11 +6608,15 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res->klass = klass;
        res->field = field;
        MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
-       if (is_field_on_inst (field))
+
+       if (is_field_on_inst (field)) {
                res->attrs = get_field_on_inst_generic_type (field)->attrs;
-       else
-               res->attrs = field->type->attrs;
-       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+               MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+       } else {
+               if (field->type)
+                       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+               res->attrs = mono_field_get_flags (field);
+       }
        CACHE_OBJECT (MonoReflectionField *, field, res, klass);
 }
 
@@ -6730,6 +6727,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
 {
        static MonoClass *System_Reflection_ParameterInfo;
        static MonoClass *System_Reflection_ParameterInfo_array;
+       MonoError error;
        MonoArray *res = NULL;
        MonoReflectionMethod *member = NULL;
        MonoReflectionParameter *param = NULL;
@@ -6754,8 +6752,12 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
                mono_memory_barrier ();
                System_Reflection_ParameterInfo_array = klass;
        }
-       
-       if (!mono_method_signature (method)->param_count)
+
+       sig = mono_method_signature_checked (method, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
+
+       if (!sig->param_count)
                return mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0);
 
        /* Note: the cache is based on the address of the signature into the method
@@ -6763,7 +6765,6 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
         */
        CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
 
-       sig = mono_method_signature (method);
        member = mono_method_get_object (domain, method, refclass);
        names = g_new (char *, sig->param_count);
        mono_method_get_param_names (method, (const char **) names);
@@ -6860,11 +6861,16 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        static MonoClass *System_Reflection_ExceptionHandlingClause = NULL;
        MonoReflectionMethodBody *ret;
        MonoMethodHeader *header;
+       MonoImage *image;
        guint32 method_rva, local_var_sig_token;
     char *ptr;
        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)
@@ -6879,26 +6885,31 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
            (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
            (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
                return NULL;
+
+       image = method->klass->image;
        header = mono_method_get_header (method);
-       
-       /* Obtain local vars signature token */
-       method_rva = mono_metadata_decode_row_col (&method->klass->image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
-       ptr = mono_image_rva_map (method->klass->image, method_rva);
-       flags = *(const unsigned char *) ptr;
-       format = flags & METHOD_HEADER_FORMAT_MASK;
-       switch (format){
-       case METHOD_HEADER_TINY_FORMAT:
-               local_var_sig_token = 0;
-               break;
-       case METHOD_HEADER_FAT_FORMAT:
-               ptr += 2;
-               ptr += 2;
-               ptr += 4;
-               local_var_sig_token = read32 (ptr);
-               break;
-       default:
-               g_assert_not_reached ();
-       }
+
+       if (!image->dynamic) {
+               /* Obtain local vars signature token */
+               method_rva = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
+               ptr = mono_image_rva_map (image, method_rva);
+               flags = *(const unsigned char *) ptr;
+               format = flags & METHOD_HEADER_FORMAT_MASK;
+               switch (format){
+               case METHOD_HEADER_TINY_FORMAT:
+                       local_var_sig_token = 0;
+                       break;
+               case METHOD_HEADER_FAT_FORMAT:
+                       ptr += 2;
+                       ptr += 2;
+                       ptr += 4;
+                       local_var_sig_token = read32 (ptr);
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+       } else
+               local_var_sig_token = 0; //FIXME
 
        ret = (MonoReflectionMethodBody*)mono_object_new (domain, System_Reflection_MethodBody);
 
@@ -7066,23 +7077,35 @@ static int
 assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        int found_sep;
        char *s;
+       gboolean quoted = FALSE;
 
        memset (assembly, 0, sizeof (MonoAssemblyName));
-       assembly->name = p;
        assembly->culture = "";
        memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
 
-       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
+       if (*p == '"') {
+               quoted = TRUE;
+               p++;
+       }
+       assembly->name = p;
+       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
                p++;
-       found_sep = 0;
-       while (g_ascii_isspace (*p) || *p == ',') {
-               *p++ = 0;
-               found_sep = 1;
-               continue;
-       }
-       /* failed */
-       if (!found_sep)
+       if (quoted) {
+               if (*p != '"')
+                       return 1;
+               *p = 0;
+               p++;
+       }
+       if (*p != ',')
                return 1;
+       *p = 0;
+       /* Remove trailing whitespace */
+       s = p - 1;
+       while (*s && g_ascii_isspace (*s))
+               *s-- = 0;
+       p ++;
+       while (g_ascii_isspace (*p))
+               p++;
        while (*p) {
                if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
                        p += 8;
@@ -7270,7 +7293,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                                        if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
                                                return 0;
 
-                                       if (fqname) {
+                                       /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
+                                       if (fqname && (*p != ']')) {
                                                char *aname;
 
                                                if (*p != ',')
@@ -7295,6 +7319,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                                                if (!*aname ||
                                                    !assembly_name_to_aname (&subinfo->assembly, aname))
                                                        return 0;
+                                       } else if (fqname && (*p == ']')) {
+                                               *p++ = 0;
                                        }
 
                                        if (i + 1 < arity) {
@@ -7442,7 +7468,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
        }
        if (!klass)
                return NULL;
-       mono_class_init (klass);
 
        if (info->type_arguments) {
                MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
@@ -7483,7 +7508,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
                } else { /* array rank */
                        klass = mono_bounded_array_class_get (klass, modval, bounded);
                }
-               mono_class_init (klass);
        }
 
        return &klass->byval_arg;
@@ -7660,14 +7684,17 @@ mono_reflection_get_token (MonoObject *obj)
        } else if (strcmp (klass->name, "FieldBuilder") == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
 
-               /* Call mono_image_create_token so the object gets added to the tokens hash table */
-               token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE, TRUE);
+               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
        } else if (strcmp (klass->name, "TypeBuilder") == 0) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
                token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
        } else if (strcmp (klass->name, "MonoType") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
-               token = mono_class_from_mono_type (type)->type_token;
+               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 = mc->type_token;
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                   strcmp (klass->name, "MonoMethod") == 0 ||
                   strcmp (klass->name, "MonoGenericMethod") == 0 ||
@@ -7780,9 +7807,18 @@ handle_enum:
                        type = mono_class_enum_basetype (t->data.klass)->type;
                        goto handle_enum;
                } else {
-                       g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
+                       MonoClass *k =  t->data.klass;
+                       
+                       if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
+                               guint64 *val = g_malloc (sizeof (guint64));
+                               *val = read64 (p);
+                               *end = p + 8;
+                               return val;
+                       }
                }
+               g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
                break;
+               
        case MONO_TYPE_STRING:
                if (*p == (char)0xFF) {
                        *end = p + 1;
@@ -7828,12 +7864,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;
@@ -8059,7 +8099,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;
@@ -8069,8 +8109,15 @@ 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)) {
+               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);
                mono_runtime_invoke (method, attr, NULL, NULL);
@@ -8171,6 +8218,9 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        guint32 i, j, num_named;
        CattrNamedArg *arginfo = NULL;
 
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
+               return;
+
        mono_class_init (method->klass);
 
        *typed_args = NULL;
@@ -8269,35 +8319,35 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        *named_args = namedargs;
 }
 
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+void
+mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
 {
-       MonoArray *typedargs, *namedargs;
-       static MonoMethod *ctor;
        MonoDomain *domain;
-       MonoObject *attr;
-       void *params [3];
+       MonoArray *typedargs, *namedargs;
+       MonoImage *image;
+       MonoMethod *method;
        CattrNamedArg *arginfo;
        int i;
 
-       mono_class_init (method->klass);
+       *ctor_args = NULL;
+       *named_args = NULL;
 
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+       if (len == 0)
+               return;
 
-       domain = mono_domain_get ();
-       if (len == 0) {
-               /* This is for Attributes with no parameters */
-               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);
-               return attr;
-       }
+       image = assembly->assembly->image;
+       method = ref_method->method;
+       domain = mono_object_domain (ref_method);
+
+       if (!mono_class_init (method->klass))
+               mono_raise_exception (mono_class_get_exception_for_failure (method->klass));
 
        mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
+       if (mono_loader_get_last_error ())
+               mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+
        if (!typedargs || !namedargs)
-               return NULL;
+               return;
 
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
@@ -8322,51 +8372,59 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
                mono_array_setref (namedargs, i, namedarg);
        }
 
-       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;
-       mono_runtime_invoke (ctor, attr, params, NULL);
-       return attr;
+       *ctor_args = typedargs;
+       *named_args = namedargs;
 }
 
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr)
 {
-       MonoArray *result;
+       static MonoMethod *ctor;
+       MonoDomain *domain;
        MonoObject *attr;
-       int i;
+       void *params [4];
 
-       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;
+       g_assert (image->assembly);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
+
+       domain = mono_domain_get ();
+       attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
+       params [0] = mono_method_get_object (domain, cattr->ctor, NULL);
+       params [1] = mono_assembly_get_object (domain, image->assembly);
+       params [2] = (gpointer)&cattr->data;
+       params [3] = &cattr->data_size;
+       mono_runtime_invoke (ctor, attr, params, NULL);
+       return attr;
 }
 
 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 ++;
                }
@@ -8374,6 +8432,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)
 {
@@ -8383,7 +8449,7 @@ mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
        
        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);
+               attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i]);
                mono_array_setref (result, i, attr);
        }
        return result;
@@ -8443,6 +8509,14 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
                        g_free (ainfo);
                        return NULL;
                }
+
+               if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
+                       /*FIXME raising an exception here doesn't make any sense*/
+                       g_warning ("Invalid custom attribute blob on image %s for index %x", image->name, idx);
+                       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;
@@ -8610,6 +8684,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
        image = method->klass->image;
        method_index = mono_method_get_index (method);
+       if (!method_index)
+               return NULL;
        ca = &image->tables [MONO_TABLE_METHOD];
 
        param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
@@ -8693,6 +8769,7 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
        if (klass == mono_defaults.monotype_class) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                klass = mono_class_from_mono_type (type);
+               /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
                cinfo = mono_custom_attrs_from_class (klass);
        } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
                MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
@@ -8793,17 +8870,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 {
@@ -8826,7 +8902,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);
 }
 
 /*
@@ -9046,8 +9124,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);
@@ -9163,6 +9241,11 @@ is_sre_generic_instance (MonoClass *class)
        return FALSE;
 }
 
+static void
+init_type_builder_generics (MonoObject *type)
+{
+}
+
 #endif /* !DISABLE_REFLECTION_EMIT */
 
 
@@ -9713,7 +9796,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                        (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
                klass->instance_size = sizeof (MonoObject);
                klass->size_inited = 1;
-               mono_class_setup_vtable_general (klass, NULL, 0);
+               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
        }
 
        mono_class_setup_mono_type (klass);
@@ -9847,7 +9930,7 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
                 * to create objects of the enum type (for use in SetConstant).
                 */
                /* FIXME: Does this mean enums can't have method overrides ? */
-               mono_class_setup_vtable_general (klass, NULL, 0);
+               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
        }
        mono_loader_unlock ();
 }
@@ -9986,8 +10069,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;
@@ -10093,6 +10175,23 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        container->type_params [i] = *param;
                }
 
+               /*
+                * The method signature might have pointers to generic parameters that belong to other methods.
+                * This is a valid SRE case, but the resulting method signature must be encoded using the proper
+                * generic parameters.
+                */
+               for (i = 0; i < m->signature->param_count; ++i) {
+                       MonoType *t = m->signature->params [i];
+                       if (t->type == MONO_TYPE_MVAR) {
+                               MonoGenericParam *gparam =  t->data.generic_param;
+                               if (gparam->num < count) {
+                                       m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
+                                       m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
+                               }
+
+                       }
+               }
+
                if (klass->generic_container) {
                        container->parent = klass->generic_container;
                        container->context.class_inst = klass->generic_container->context.class_inst;
@@ -10243,10 +10342,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;
@@ -10254,7 +10355,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);
        }
@@ -10400,6 +10502,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);
 }
@@ -10423,7 +10528,7 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
 
        context = mono_class_get_context (klass);
 
-       if (klass->method.count) {
+       if (klass->method.count && klass->methods) {
                /* Find the already created inflated method */
                for (i = 0; i < klass->method.count; ++i) {
                        g_assert (klass->methods [i]->is_inflated);
@@ -10517,11 +10622,11 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        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);
+       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);
@@ -10553,19 +10658,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)
 {
@@ -10577,6 +10699,25 @@ fix_partial_generic_class (MonoClass *klass)
                return;
 
        dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
+       if (klass->parent != gklass->parent) {
+               MonoError error;
+               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, &error);
+               if (mono_error_ok (&error)) {
+                       MonoClass *parent = mono_class_from_mono_type (parent_type);
+                       mono_metadata_free_type (parent_type);
+                       if (parent != klass->parent) {
+                               /*fool mono_class_setup_parent*/
+                               klass->supertypes = NULL;
+                               mono_class_setup_parent (klass, parent);
+                       }
+               } else {
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       mono_error_cleanup (&error);
+                       if (gklass->wastypebuilder)
+                               klass->wastypebuilder = TRUE;
+                       return;
+               }
+       }
 
        if (!dgclass->initialized)
                return;
@@ -10672,8 +10813,12 @@ ensure_runtime_vtable (MonoClass *klass)
        }
 
        if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
-               for (i = 0; i < klass->method.count; ++i)
-                       klass->methods [i]->slot = i;
+               int slot_num = 0;
+               for (i = 0; i < klass->method.count; ++i) {
+                       MonoMethod *im = klass->methods [i];
+                       if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
+                               im->slot = slot_num++;
+               }
                
                klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
                mono_class_setup_interface_offsets (klass);
@@ -10692,6 +10837,45 @@ ensure_runtime_vtable (MonoClass *klass)
         */
 }
 
+static MonoMethod*
+mono_reflection_method_get_handle (MonoObject *method)
+{
+       MonoClass *class = mono_object_class (method);
+       if (is_sr_mono_method (class) || is_sr_mono_generic_method (class)) {
+               MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
+               return sr_method->method;
+       }
+       if (is_sre_method_builder (class)) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
+               return mb->mhandle;
+       }
+       if (is_sre_method_on_tb_inst (class)) {
+               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
+               MonoMethod *result;
+               /*FIXME move this to a proper method and unify with resolve_object*/
+               if (m->method_args) {
+                       result = mono_reflection_method_on_tb_inst_get_handle (m);
+               } else {
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
+                       MonoMethod *mono_method;
+
+                       if (is_sre_method_builder (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+                       else if (is_sr_mono_method (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethod *)m->mb)->method;
+                       else
+                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+                       result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
+               }
+               return result;
+       }
+
+       g_error ("Can't handle methods of type %s:%s", class->name_space, class->name);
+       return NULL;
+}
+
 void
 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
 {
@@ -10728,13 +10912,9 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
                        if (mb->override_method) {
-                               (*overrides) [onum * 2] = 
-                                       mb->override_method->method;
-                               (*overrides) [onum * 2 + 1] =
-                                       mb->mhandle;
+                               (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
+                               (*overrides) [onum * 2 + 1] = mb->mhandle;
 
-                               /* FIXME: What if 'override_method' is a MethodBuilder ? */
-                               g_assert (mb->override_method->method);
                                g_assert (mb->mhandle);
 
                                onum ++;
@@ -10804,6 +10984,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                fb->handle = field;
                mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
+               if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+                       klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
+               }
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
@@ -10853,6 +11036,21 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error)
                        properties [i].set = pb->set_method->mhandle;
 
                mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
+               if (pb->def_value) {
+                       guint32 len, idx;
+                       const char *p, *p2;
+                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+                       if (!klass->ext->prop_def_values)
+                               klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
+                       properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
+                       idx = encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+                       /* Copy the data from the blob since it might get realloc-ed */
+                       p = assembly->blob.data + idx;
+                       len = mono_metadata_decode_blob_size (p, &p2);
+                       len += p2 - p;
+                       klass->ext->prop_def_values [i].data = mono_image_alloc (image, len);
+                       memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+               }
        }
 }
 
@@ -11049,6 +11247,12 @@ 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;
+       mono_class_setup_parent (klass, klass->parent);
+       mono_class_setup_mono_type (klass);
 
 #if 0
        if (!((MonoDynamicImage*)klass->image)->run) {
@@ -11144,10 +11348,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) {
@@ -11171,10 +11382,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;
@@ -11243,15 +11450,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);
@@ -11309,7 +11548,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) {
@@ -11335,16 +11579,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:
@@ -11358,6 +11592,19 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
        return mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL;
 }
 
+MonoMethodSignature *
+mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token)
+{
+       MonoMethodSignature *sig;
+       g_assert (image->dynamic);
+
+       sig = g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
+       if (sig)
+               return sig;
+
+       return mono_method_signature (method);
+}
+
 #ifndef DISABLE_REFLECTION_EMIT
 
 /**
@@ -11431,6 +11678,10 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                g_assert (result);
        } else if (strcmp (obj->vtable->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));
+
                if (context) {
                        MonoType *inflated = mono_class_inflate_generic_type (type, context);
                        result = mono_class_from_mono_type (inflated);
@@ -11634,6 +11885,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
                if (m->method_args) {
                        result = mono_reflection_method_on_tb_inst_get_handle (m);
+                       if (context)
+                               result = mono_class_inflate_generic_method (result, context);
                } else {
                        MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
                        MonoClass *inflated_klass = mono_class_from_mono_type (type);
@@ -11765,7 +12018,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 
 guint32
 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                                                gboolean create_methodspec, gboolean register_token)
+                                                gboolean create_open_instance, gboolean register_token)
 {
        g_assert_not_reached ();
        return 0;
@@ -11844,6 +12097,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 */