2010-01-03 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / reflection.c
index e472ed31d38c922267bcc6d1d4f094a04080fd2d..7c0fb0c3c3f21382eab91fc1436ff9f3ce375b95 100644 (file)
@@ -38,6 +38,9 @@
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/utils/mono-string.h>
+#include <mono/utils/mono-error-internals.h>
+
 
 #if HAVE_SGEN_GC
 static void* reflection_info_desc = NULL;
@@ -52,6 +55,9 @@ static void* reflection_info_desc = NULL;
 #define MOVING_GC_REGISTER(addr)
 #endif
 
+static gboolean is_usertype (MonoReflectionType *ref);
+static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
+
 typedef struct {
        char *p;
        char *buf;
@@ -178,9 +184,17 @@ static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflecti
 static gboolean is_sre_array (MonoClass *class);
 static gboolean is_sre_byref (MonoClass *class);
 static gboolean is_sre_pointer (MonoClass *class);
+static gboolean is_sre_type_builder (MonoClass *class);
+static gboolean is_sre_method_builder (MonoClass *class);
+static gboolean is_sre_ctor_builder (MonoClass *class);
+static gboolean is_sre_field_builder (MonoClass *class);
+static gboolean is_sr_mono_method (MonoClass *class);
+static gboolean is_sr_mono_cmethod (MonoClass *class);
+static gboolean is_sr_mono_field (MonoClass *class);
+
 static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method);
 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
-static MonoMethod * inflate_method (MonoReflectionGenericClass *type, MonoObject *obj);
+static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
 
 #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 {  \
@@ -1616,11 +1630,12 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
+/*field_image is the image to which the eventual custom mods have been encoded against*/
 static guint32
-fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
+fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
 {
        SigBuffer buf;
-       guint32 idx, i;
+       guint32 idx, i, token;
 
        if (!assembly->save)
                return 0;
@@ -1629,14 +1644,22 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
        
        sigbuffer_add_value (&buf, 0x06);
        /* encode custom attributes before the type */
-       /* FIXME: This should probably go in encode_type () */
        if (type->num_mods) {
                for (i = 0; i < type->num_mods; ++i) {
+                       if (field_image) {
+                               MonoClass *class = mono_class_get (field_image, type->modifiers [i].token);
+                               g_assert (class);
+                               token = mono_image_typedef_or_ref (assembly, &class->byval_arg);
+                       } else {
+                               token = type->modifiers [i].token;
+                       }
+
                        if (type->modifiers [i].required)
                                sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
                        else
                                sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
-                       sigbuffer_add_value (&buf, type->modifiers [i].token);
+
+                       sigbuffer_add_value (&buf, token);
                }
        }
        encode_type (assembly, type, &buf);
@@ -2542,12 +2565,12 @@ mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMe
        if (mb->generic_params && create_methodspec) 
                return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb);
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
        if (token)
                return token;
 
        token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb);
-       g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2558,7 +2581,7 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
        ReflectionMethodBuilder rmb;
        char *name;
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, mb));
        if (token)
                return token;
 
@@ -2569,7 +2592,7 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
                name, method_builder_encode_signature (assembly, &rmb));
 
        g_free (name);
-       g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
+       mono_g_hash_table_insert (assembly->handleref_managed, mb, GUINT_TO_POINTER(token));
        return token;
 }
 #endif
@@ -2586,16 +2609,29 @@ is_field_on_inst (MonoClassField *field)
 static MonoType*
 get_field_on_inst_generic_type (MonoClassField *field)
 {
+       MonoClass *class, *gtd;
        MonoDynamicGenericClass *dgclass;
        int field_index;
 
        g_assert (is_field_on_inst (field));
 
        dgclass = (MonoDynamicGenericClass*)field->parent->generic_class;
-       field_index = field - dgclass->fields;
 
-       g_assert (field_index >= 0 && field_index < dgclass->count_fields);
-       return dgclass->field_generic_types [field_index];
+       if (field >= dgclass->fields && field - dgclass->fields < dgclass->count_fields) {
+               field_index = field - dgclass->fields;
+               return dgclass->field_generic_types [field_index];              
+       }
+
+       class = field->parent;
+       gtd = class->generic_class->container_class;
+
+       if (field >= class->fields && field - class->fields < class->field.count) {
+               field_index = field - class->fields;
+               return gtd->fields [field_index].type;
+       }
+
+       g_assert_not_reached ();
+       return 0;
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -2606,7 +2642,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
        guint32 token;
        MonoClassField *field;
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
        if (token)
                return token;
        g_assert (f->field->parent);
@@ -2623,8 +2659,8 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
        }
        token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg, 
                                                                                        mono_field_get_name (f->field),  
-                                                                                       fieldref_encode_signature (assembly, type));
-       g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
+                                                                                       fieldref_encode_signature (assembly, field->parent->image, type));
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2635,24 +2671,39 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
        MonoClass *klass;
        MonoGenericClass *gclass;
        MonoDynamicGenericClass *dgclass;
-       MonoReflectionFieldBuilder *fb = f->fb;
        MonoType *type;
        char *name;
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
        if (token)
                return token;
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
-       klass = mono_class_from_mono_type (type);
-       gclass = type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
+       if (is_sre_field_builder (mono_object_class (f->fb))) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)f->fb;
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+               klass = mono_class_from_mono_type (type);
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
+               dgclass = (MonoDynamicGenericClass *) gclass;
+
+               name = mono_string_to_utf8 (fb->name);
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, 
+                                                                                               field_encode_signature (assembly, fb));
+               g_free (name);          
+       } else if (is_sr_mono_field (mono_object_class (f->fb))) {
+               guint32 sig;
+               MonoClassField *field = ((MonoReflectionField *)f->fb)->field;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)f->inst);
+               klass = mono_class_from_mono_type (type);
 
-       name = mono_string_to_utf8 (fb->name);
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, 
-                                                                                       field_encode_signature (assembly, fb));
-       g_free (name);
-       g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token));
+               sig = fieldref_encode_signature (assembly, field->parent->image, field->type);
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (f->fb));
+               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+       }
+
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -2662,33 +2713,50 @@ mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCto
        guint32 sig, token;
        MonoClass *klass;
        MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoReflectionCtorBuilder *cb = c->cb;
-       ReflectionMethodBuilder rmb;
        MonoType *type;
-       char *name;
 
        /* A ctor cannot be a generic method, so we can ignore create_methodspec */
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, c));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, c));
        if (token)
                return token;
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
-       klass = mono_class_from_mono_type (type);
-       gclass = type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
 
-       reflection_methodbuilder_from_ctor_builder (&rmb, cb);
+       if (is_sre_ctor_builder (mono_object_class (c->cb))) {
+               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder *)c->cb;
+               MonoDynamicGenericClass *dgclass;
+               ReflectionMethodBuilder rmb;
+               char *name;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+               klass = mono_class_from_mono_type (type);
 
-       name = mono_string_to_utf8 (rmb.name);
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
+               dgclass = (MonoDynamicGenericClass *) gclass;
 
-       sig = method_builder_encode_signature (assembly, &rmb);
+               reflection_methodbuilder_from_ctor_builder (&rmb, cb);
 
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
-       g_free (name);
+               name = mono_string_to_utf8 (rmb.name);
 
-       g_hash_table_insert (assembly->handleref, c, GUINT_TO_POINTER (token));
+               sig = method_builder_encode_signature (assembly, &rmb);
+
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+               g_free (name);
+       } else if (is_sr_mono_cmethod (mono_object_class (c->cb))) {
+               MonoMethod *mm = ((MonoReflectionMethod *)c->cb)->method;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)c->inst);
+               klass = mono_class_from_mono_type (type);
+
+               sig = method_encode_signature (assembly, mono_method_signature (mm));
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (c->cb));
+               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+       }
+
+
+       mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -2729,13 +2797,9 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI
 static guint32
 mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec)
 {
-       guint32 sig, token;
-       MonoClass *klass;
-       MonoGenericClass *gclass;
-       MonoReflectionMethodBuilder *mb = m->mb;
-       ReflectionMethodBuilder rmb;
+       guint32 sig, token = 0;
        MonoType *type;
-       char *name;
+       MonoClass *klass;
 
        if (m->method_args) {
                MonoMethod *inflated;
@@ -2748,24 +2812,43 @@ mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionM
                return token;
        }
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
        if (token)
                return token;
-       type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
-       klass = mono_class_from_mono_type (type);
-       gclass = type->data.generic_class;
-       g_assert (gclass->is_dynamic);
 
-       reflection_methodbuilder_from_method_builder (&rmb, mb);
+       if (is_sre_method_builder (mono_object_class (m->mb))) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
+               MonoGenericClass *gclass;
+               ReflectionMethodBuilder rmb;
+               char *name;
 
-       name = mono_string_to_utf8 (rmb.name);
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+               klass = mono_class_from_mono_type (type);
+               gclass = type->data.generic_class;
+               g_assert (gclass->is_dynamic);
 
-       sig = method_builder_encode_signature (assembly, &rmb);
+               reflection_methodbuilder_from_method_builder (&rmb, mb);
 
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
-       g_free (name);
+               name = mono_string_to_utf8 (rmb.name);
 
-       g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER (token));
+               sig = method_builder_encode_signature (assembly, &rmb);
+
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
+               g_free (name);          
+       } else if (is_sr_mono_method (mono_object_class (m->mb))) {
+               MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;
+
+               type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+               klass = mono_class_from_mono_type (type);
+
+               sig = method_encode_signature (assembly, mono_method_signature (mm));
+               token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
+       } else {
+               char *name = mono_type_get_full_name (mono_object_class (m->mb));
+               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+       }
+
+       mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -2995,7 +3078,7 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        guint32 token, pclass, parent, sig;
        gchar *name;
 
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb));
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, fb));
        if (token)
                return token;
 
@@ -3006,10 +3089,10 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        /* 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, custom);
+               sig = fieldref_encode_signature (assembly, NULL, custom);
                g_free (custom);
        } else {
-               sig = fieldref_encode_signature (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
+               sig = fieldref_encode_signature (assembly, NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
        }
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
@@ -3030,7 +3113,7 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
 
        token = MONO_TOKEN_MEMBER_REF | table->next_idx;
        table->next_idx ++;
-       g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token));
+       mono_g_hash_table_insert (assembly->handleref_managed, fb, GUINT_TO_POINTER(token));
        g_free (name);
        return token;
 }
@@ -4865,6 +4948,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->field_to_table_idx = g_hash_table_new (NULL, NULL);
        image->method_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);
        image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
        image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
@@ -4927,6 +5011,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                g_hash_table_destroy (di->typeref);
        if (di->handleref)
                g_hash_table_destroy (di->handleref);
+       if (di->handleref_managed)
+               mono_g_hash_table_destroy (di->handleref_managed);
        if (di->tokens)
                mono_g_hash_table_destroy (di->tokens);
        if (di->generic_def_objects)
@@ -4952,6 +5038,7 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                                g_free ((char*)mono_generic_param_info (param)->name);
                                g_free (param);
                        }
+                       mono_gc_deregister_root ((char*) &entry->gparam);
                        g_free (entry);
                }
                g_ptr_array_free (di->gen_params, TRUE);
@@ -5041,6 +5128,7 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 
        assembly->run = assemblyb->access != 2;
        assembly->save = assemblyb->access != 1;
+       assembly->domain = domain;
 
        image = create_dynamic_mono_image (assembly, mono_string_to_utf8 (assemblyb->name), g_strdup ("RefEmit_YouForgotToDefineAModule"));
        image->initial_image = TRUE;
@@ -5906,16 +5994,24 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
        MonoDynamicImage *image = moduleb->dynamic_image;
        MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
        if (!image) {
+               MonoError error;
                int module_count;
                MonoImage **new_modules;
                MonoImage *ass;
+               char *name, *fqname;
                /*
                 * FIXME: we already created an image in mono_image_basic_init (), but
                 * we don't know which module it belongs to, since that is only 
                 * determined at assembly save time.
                 */
                /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
-               image = create_dynamic_mono_image (ab->dynamic_assembly, mono_string_to_utf8 (ab->name), mono_string_to_utf8 (moduleb->module.fqname));
+               name = mono_string_to_utf8 (ab->name);
+               fqname = mono_string_to_utf8_checked (moduleb->module.fqname, &error);
+               if (!mono_error_ok (&error)) {
+                       g_free (name);
+                       mono_error_raise_exception (&error);
+               }
+               image = create_dynamic_mono_image (ab->dynamic_assembly, name, fqname);
 
                moduleb->module.image = &image->image;
                moduleb->dynamic_image = image;
@@ -6160,6 +6256,8 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
        MonoArray *type_args;
        int i;
 
+       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");
@@ -6283,9 +6381,28 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        }
 
        if (klass->reflection_info && !klass->wastypebuilder) {
+               gboolean is_type_done = TRUE;
+               /* Generic parameters have reflection_info set but they are not finished together with their enclosing type.
+                * We must ensure that once a type is finished we don't return a GenericTypeParameterBuilder.
+                * We can't simply close the types as this will interfere with other parts of the generics machinery.
+               */
+               if (klass->byval_arg.type == MONO_TYPE_MVAR || klass->byval_arg.type == MONO_TYPE_VAR) {
+                       MonoGenericParam *gparam = klass->byval_arg.data.generic_param;
+
+                       if (gparam->owner && gparam->owner->is_method) {
+                               MonoMethod *method = gparam->owner->owner.method;
+                               if (method && mono_class_get_generic_type_definition (method->klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       } else if (gparam->owner && !gparam->owner->is_method) {
+                               MonoClass *klass = gparam->owner->owner.klass;
+                               if (klass && mono_class_get_generic_type_definition (klass)->wastypebuilder)
+                                       is_type_done = FALSE;
+                       }
+               } 
+
                /* g_assert_not_reached (); */
                /* should this be considered an error condition? */
-               if (!type->byref) {
+               if (is_type_done && !type->byref) {
                        mono_domain_unlock (domain);
                        mono_loader_unlock ();
                        return klass->reflection_info;
@@ -7235,7 +7352,7 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
 
                while ((klass = mono_class_get_nested_types (parent, &iter))) {
                        if (ignorecase) {
-                               if (g_strcasecmp (klass->name, mod->data) == 0)
+                               if (mono_utf8_strcasecmp (klass->name, mod->data) == 0)
                                        break;
                        } else {
                                if (strcmp (klass->name, mod->data) == 0)
@@ -7313,11 +7430,12 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
 static MonoType*
 mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase)
 {
-       MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (mono_domain_get (), assembly);
+       MonoReflectionAssemblyBuilder *abuilder;
        MonoType *type;
        int i;
 
        g_assert (assembly->dynamic);
+       abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (((MonoDynamicAssembly*)assembly)->domain, assembly);
 
        /* Enumerate all modules */
 
@@ -7658,6 +7776,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));
                g_free (val);
                return obj;
@@ -7953,51 +8072,48 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
 
        return attr;
 }
-
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+       
+/*
+ * mono_reflection_create_custom_attr_data_args:
+ *
+ *   Create an array of typed and named arguments from the cattr blob given by DATA.
+ * TYPED_ARGS and NAMED_ARGS will contain the objects representing the arguments,
+ * NAMED_ARG_INFO will contain information about the named arguments.
+ */
+void
+mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info)
 {
        MonoArray *typedargs, *namedargs;
        MonoClass *attrklass;
-       static MonoMethod *ctor;
        MonoDomain *domain;
-       MonoObject *attr;
        const char *p = (const char*)data;
        const char *named;
        guint32 i, j, num_named;
-       void *params [3];
+       CattrNamedArg *arginfo = NULL;
 
        mono_class_init (method->klass);
 
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
-
+       *typed_args = NULL;
+       *named_args = NULL;
+       *named_arg_info = NULL;
+       
        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;
-       }
 
        if (len < 2 || read16 (p) != 0x0001) /* Prolog */
-               return NULL;
+               return;
 
        typedargs = mono_array_new (domain, mono_get_object_class (), mono_method_signature (method)->param_count);
        
        /* skip prolog */
        p += 2;
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
-               MonoObject *obj, *typedarg;
+               MonoObject *obj;
                void *val;
 
                val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p);
                obj = type_is_reference (mono_method_signature (method)->params [i]) ? 
                        val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val);
-               typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
-               mono_array_setref (typedargs, i, typedarg);
+               mono_array_setref (typedargs, i, obj);
 
                if (!type_is_reference (mono_method_signature (method)->params [i]))
                        g_free (val);
@@ -8008,6 +8124,10 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
        namedargs = mono_array_new (domain, mono_get_object_class (), num_named);
        named += 2;
        attrklass = method->klass;
+
+       arginfo = g_new0 (CattrNamedArg, num_named);
+       *named_arg_info = arginfo;
+
        for (j = 0; j < num_named; j++) {
                gint name_len;
                char *name, named_type, data_type;
@@ -8032,36 +8152,96 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
                name [name_len] = 0;
                named += name_len;
                if (named_type == 0x53) {
-                       MonoObject *obj, *typedarg, *namedarg;
+                       MonoObject *obj;
                        MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
-                       void *minfo, *val = load_cattr_value (image, field->type, named, &named);
-                       
-                       minfo = mono_field_get_object (domain, NULL, field);
+                       void *val;
+
+                       arginfo [j].type = field->type;
+                       arginfo [j].field = field;
+
+                       val = load_cattr_value (image, field->type, named, &named);
                        obj = type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val);
-                       typedarg = create_cattr_typed_arg (field->type, obj);
-                       namedarg = create_cattr_named_arg (minfo, typedarg);
-                       mono_array_setref (namedargs, j, namedarg);
+                       mono_array_setref (namedargs, j, obj);
                        if (!type_is_reference (field->type))
                                g_free (val);
                } else if (named_type == 0x54) {
-                       MonoObject *obj, *typedarg, *namedarg;
+                       MonoObject *obj;
                        MonoType *prop_type;
-                       void *val, *minfo;
                        MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
+                       void *val;
 
                        prop_type = prop->get? mono_method_signature (prop->get)->ret :
                             mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
-                       minfo =  mono_property_get_object (domain, NULL, prop);
+
+                       arginfo [j].type = prop_type;
+                       arginfo [j].prop = prop;
+
                        val = load_cattr_value (image, prop_type, named, &named);
                        obj = type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val);
-                       typedarg = create_cattr_typed_arg (prop_type, obj);
-                       namedarg = create_cattr_named_arg (minfo, typedarg);
-                       mono_array_setref (namedargs, j, namedarg);
+                       mono_array_setref (namedargs, j, obj);
                        if (!type_is_reference (prop_type))
                                g_free (val);
                }
                g_free (name);
        }
+
+       *typed_args = typedargs;
+       *named_args = namedargs;
+}
+
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+{
+       MonoArray *typedargs, *namedargs;
+       static MonoMethod *ctor;
+       MonoDomain *domain;
+       MonoObject *attr;
+       void *params [3];
+       CattrNamedArg *arginfo;
+       int i;
+
+       mono_class_init (method->klass);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+
+       domain = mono_domain_get ();
+       if (len == 0) {
+               /* This is for Attributes with no parameters */
+               attr = mono_object_new (domain, 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;
+       }
+
+       mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
+       if (!typedargs || !namedargs)
+               return NULL;
+
+       for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+               MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
+               MonoObject *typedarg;
+
+               typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
+               mono_array_setref (typedargs, i, typedarg);
+       }
+
+       for (i = 0; i < mono_array_length (namedargs); ++i) {
+               MonoObject *obj = mono_array_get (namedargs, MonoObject*, i);
+               MonoObject *typedarg, *namedarg, *minfo;
+
+               if (arginfo [i].prop)
+                       minfo = (MonoObject*)mono_property_get_object (domain, NULL, arginfo [i].prop);
+               else
+                       minfo = (MonoObject*)mono_field_get_object (domain, NULL, arginfo [i].field);
+
+               typedarg = create_cattr_typed_arg (arginfo [i].type, obj);
+               namedarg = create_cattr_named_arg (minfo, typedarg);
+
+               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;
@@ -8340,6 +8520,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
                /* Need to copy since it will be freed later */
                ainfo = aux->param_cattr [param];
+               if (!ainfo)
+                       return NULL;
                size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
                res = g_malloc0 (size);
                memcpy (res, ainfo, size);
@@ -8559,13 +8741,13 @@ mono_reflection_get_custom_attrs_data (MonoObject *obj)
 static MonoReflectionType*
 mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
 {
-        MonoMethod *method_get_underlying_system_type;
+       static MonoMethod *method_get_underlying_system_type = NULL;
+       MonoMethod *usertype_method;
 
-        method_get_underlying_system_type = mono_object_get_virtual_method ((MonoObject *) t,
-                                                                            mono_class_get_method_from_name (mono_object_class (t),
-                                                                                                             "get_UnderlyingSystemType",
-                                                                                                             0));
-        return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
+       if (!method_get_underlying_system_type)
+               method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
+       usertype_method = mono_object_get_virtual_method ((MonoObject *) t, method_get_underlying_system_type);
+        return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -8576,13 +8758,6 @@ is_corlib_type (MonoClass *class)
        return class->image == mono_defaults.corlib;
 }
 
-static gboolean
-is_usertype (MonoReflectionType *ref)
-{
-       MonoClass *class = mono_object_class (ref);
-       return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;
-}
-
 #define check_corlib_type_cached(_class, _namespace, _name) do { \
        static MonoClass *cached_class; \
        if (cached_class) \
@@ -8618,6 +8793,49 @@ is_sre_generic_instance (MonoClass *class)
        check_corlib_type_cached (class, "System.Reflection", "MonoGenericClass");
 }
 
+static gboolean
+is_sre_type_builder (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection.Emit", "TypeBuilder");
+}
+
+static gboolean
+is_sre_method_builder (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection.Emit", "MethodBuilder");
+}
+
+static gboolean
+is_sre_ctor_builder (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorBuilder");
+}
+
+static gboolean
+is_sre_field_builder (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection.Emit", "FieldBuilder");
+}
+
+static gboolean
+is_sr_mono_method (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
+}
+
+static gboolean
+is_sr_mono_cmethod (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoCMethod");
+}
+
+static gboolean
+is_sr_mono_field (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoField");
+}
+
+
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref)
 {
@@ -8629,7 +8847,8 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
 
        if (is_usertype (ref)) {
                ref = mono_reflection_type_get_underlying_system_type (ref);
-               g_assert (!is_usertype (ref)); /*FIXME fail better*/
+               if (ref == NULL || is_usertype (ref))
+                       return NULL;
                if (ref->type)
                        return ref->type;
        }
@@ -8673,9 +8892,13 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
                for (i = 0; i < count; ++i) {
                        MonoReflectionType *t = mono_array_get (gclass->type_arguments, gpointer, i);
                        types [i] = mono_reflection_type_get_handle (t);
+                       if (!types[i]) {
+                               g_free (types);
+                               return NULL;
+                       }
                }
 
-               res = mono_reflection_bind_generic_parameters ((MonoReflectionType*)gclass->generic_type, count, types);
+               res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types);
                g_free (types);
                g_assert (res);
                gclass->type.type = res;
@@ -8686,20 +8909,7 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
        return NULL;
 }
 
-static MonoReflectionType*
-mono_reflection_type_resolve_user_types (MonoReflectionType *type)
-{
-       if (!type || type->type)
-               return type;
-
-       if (is_usertype (type)) {
-               type = mono_reflection_type_get_underlying_system_type (type);
-               if (is_usertype (type))
-                       mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
-       }
 
-       return type;
-}
 
 void
 mono_reflection_create_unmanaged_type (MonoReflectionType *type)
@@ -8707,6 +8917,33 @@ mono_reflection_create_unmanaged_type (MonoReflectionType *type)
        mono_reflection_type_get_handle (type);
 }
 
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+       MonoType *res = mono_reflection_type_get_handle (type);
+       MonoDomain *domain = mono_object_domain ((MonoObject*)type);
+       MonoClass *class;
+
+       if (!res)
+               mono_raise_exception (mono_get_exception_argument (NULL, "Invalid generic instantiation, one or more arguments are not proper user types"));
+
+       class = mono_class_from_mono_type (res);
+
+       mono_loader_lock (); /*same locking as mono_type_get_object*/
+       mono_domain_lock (domain);
+
+       if (!class->image->dynamic) {
+               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);
+               mono_g_hash_table_insert (domain->type_hash, res, type);
+       }
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+}
+
 /**
  * LOCKING: Assumes the loader lock is held.
  */
@@ -8797,6 +9034,27 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
 }
 #endif /* !DISABLE_REFLECTION_EMIT */
 
+static gboolean
+is_usertype (MonoReflectionType *ref)
+{
+       MonoClass *class = mono_object_class (ref);
+       return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;
+}
+
+static MonoReflectionType*
+mono_reflection_type_resolve_user_types (MonoReflectionType *type)
+{
+       if (!type || type->type)
+               return type;
+
+       if (is_usertype (type)) {
+               type = mono_reflection_type_get_underlying_system_type (type);
+               if (is_usertype (type))
+                       mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
+       }
+
+       return type;
+}
 /*
  * Encode a value in a custom attribute stream of bytes.
  * The value to encode is either supplied as an object in argument val
@@ -9196,6 +9454,7 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
 void
 mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 {
+       MonoError error;
        MonoClass *klass, *parent;
 
        MONO_ARCH_SAVE_REGS;
@@ -9233,8 +9492,12 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        klass->image = &tb->module->dynamic_image->image;
 
        klass->inited = 1; /* we lie to the runtime */
-       klass->name = mono_string_to_utf8_image (klass->image, tb->name);
-       klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace);
+       klass->name = mono_string_to_utf8_image (klass->image, tb->name, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
+       klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
        klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
        klass->flags = tb->attrs;
        
@@ -9242,11 +9505,22 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
        klass->element_class = klass;
 
-       MOVING_GC_REGISTER (&klass->reflection_info);
-       klass->reflection_info = tb;
+       if (klass->reflection_info == NULL) {
+
+               MOVING_GC_REGISTER (&klass->reflection_info);
+               klass->reflection_info = tb;
 
-       /* Put into cache so mono_class_get () will find it */
-       mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
+               /* Put into cache so mono_class_get () will find it.
+               Skip nested types as those should not be available on the global scope. */
+               if (!tb->nesting_type) {
+                       mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
+               } else {
+                       klass->image->reflection_info_unregister_classes =
+                               g_slist_prepend (klass->image->reflection_info_unregister_classes, klass);
+               }
+       } else {
+               g_assert (klass->reflection_info == tb);
+       }
 
        mono_g_hash_table_insert (tb->module->dynamic_image->tokens,
                GUINT_TO_POINTER (MONO_TOKEN_TYPE_DEF | tb->table_idx), tb);
@@ -9289,6 +9563,11 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
        
        mono_loader_unlock ();
+       return;
+
+failure:
+       mono_loader_unlock ();
+       mono_error_raise_exception (&error);
 }
 
 /*
@@ -9498,6 +9777,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                         ReflectionMethodBuilder *rmb,
                                         MonoMethodSignature *sig)
 {
+       MonoError error;
        MonoMethod *m;
        MonoMethodNormal *pm;
        MonoMarshalSpec **specs;
@@ -9506,6 +9786,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        gboolean dynamic;
        int i;
 
+       mono_error_init (&error);
        /*
         * Methods created using a MethodBuilder should have their memory allocated
         * inside the image mempool, while dynamic methods should have their memory
@@ -9533,7 +9814,8 @@ 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);
+       m->name = mono_string_to_utf8_image (image, rmb->name, &error);
+       g_assert (mono_error_ok (&error));
        m->klass = klass;
        m->signature = sig;
        m->skip_visibility = rmb->skip_visibility;
@@ -9550,8 +9832,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
                method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
 
-               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry) : image_strdup (image, m->name);
-               method_aux->dll = mono_string_to_utf8_image (image, rmb->dll);
+               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, &error) : image_strdup (image, m->name);
+               g_assert (mono_error_ok (&error));
+               method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, &error);
+               g_assert (mono_error_ok (&error));
                
                ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
 
@@ -9618,17 +9902,17 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
        if (rmb->generic_params) {
                int count = mono_array_length (rmb->generic_params);
-               MonoGenericContainer *container;
+               MonoGenericContainer *container = rmb->generic_container;
+
+               g_assert (container);
 
-               container = rmb->generic_container;
-               if (container) {
-                       m->is_generic = TRUE;
-                       mono_method_set_generic_container (m, container);
-               }
                container->type_argc = count;
                container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
                container->owner.method = m;
 
+               m->is_generic = TRUE;
+               mono_method_set_generic_container (m, container);
+
                for (i = 0; i < count; i++) {
                        MonoReflectionGenericParam *gp =
                                mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
@@ -9693,8 +9977,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        memcpy ((gpointer)method_aux->param_defaults [i], p, len);
                                }
 
-                               if (pb->name)
-                                       method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name);
+                               if (pb->name) {
+                                       method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, &error);
+                                       g_assert (mono_error_ok (&error));
+                               }
                                if (pb->cattrs) {
                                        if (!method_aux->param_cattr)
                                                method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
@@ -9823,15 +10109,18 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
 
        domain = mono_object_domain (type);
 
-       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+       if (is_sre_type_builder (mono_object_class (type))) {
                tb = (MonoReflectionTypeBuilder *) type;
 
                is_dynamic = TRUE;
-       } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
+       } else if (is_sre_generic_instance (mono_object_class (type))) {
                MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
+               MonoReflectionType *gtd = rgi->generic_type;
 
-               tb = rgi->generic_type;
-               is_dynamic = TRUE;
+               if (is_sre_type_builder (mono_object_class (gtd))) {
+                       tb = (MonoReflectionTypeBuilder *)gtd;
+                       is_dynamic = TRUE;
+               }
        }
 
        /* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
@@ -9884,6 +10173,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
 
        MONO_ARCH_SAVE_REGS;
 
+       /*FIXME but this no longer should happen*/
        if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
 #ifndef DISABLE_REFLECTION_EMIT
                MonoReflectionMethodBuilder *mb = NULL;
@@ -9926,6 +10216,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        inflated = mono_class_inflate_generic_method (method, &tmp_context);
        imethod = (MonoMethodInflated *) inflated;
 
+       /*FIXME but I think this is no longer necessary*/
        if (method->klass->image->dynamic) {
                MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
                /*
@@ -9983,12 +10274,24 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
 }
 
 static MonoMethod *
-inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
+inflate_method (MonoReflectionType *type, MonoObject *obj)
 {
        MonoMethod *method;
        MonoClass *gklass;
 
-       gklass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)type->generic_type));
+       MonoClass *type_class = mono_object_class (type);
+
+       if (is_sre_generic_instance (type_class)) {
+               MonoReflectionGenericClass *mgc = (MonoReflectionGenericClass*)type;
+               gklass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mgc->generic_type));
+       } else if (is_sre_type_builder (type_class)) {
+               gklass = mono_class_from_mono_type (mono_reflection_type_get_handle (type));
+       } else if (type->type) {
+               gklass = mono_class_from_mono_type (type->type);
+               gklass = mono_class_get_generic_type_definition (gklass);
+       } else {
+               g_error ("Can't handle type %s", mono_type_get_full_name (mono_object_class (type)));
+       }
 
        if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
                if (((MonoReflectionMethodBuilder*)obj)->mhandle)
@@ -10026,7 +10329,9 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        g_assert (gtype->type == MONO_TYPE_GENERICINST);
        gclass = gtype->data.generic_class;
 
-       g_assert (gclass->is_dynamic);
+       if (!gclass->is_dynamic)
+               return;
+
        dgclass = (MonoDynamicGenericClass *) gclass;
 
        if (dgclass->initialized)
@@ -10038,27 +10343,23 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        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->count_properties = properties ? mono_array_length (properties) : 0;
-       dgclass->count_events = events ? mono_array_length (events) : 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->properties = g_new0 (MonoProperty, dgclass->count_properties);
-       dgclass->events = g_new0 (MonoEvent, dgclass->count_events);
        dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
        dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
 
        for (i = 0; i < dgclass->count_methods; i++) {
                MonoObject *obj = mono_array_get (methods, gpointer, i);
 
-               dgclass->methods [i] = inflate_method (type, obj);
+               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 (type, obj);
+               dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
        }
 
        for (i = 0; i < dgclass->count_fields; i++) {
@@ -10089,90 +10390,59 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                }
        }
 
-       for (i = 0; i < dgclass->count_properties; i++) {
-               MonoObject *obj = mono_array_get (properties, gpointer, i);
-               MonoProperty *property = &dgclass->properties [i];
-
-               if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
-                       MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
-
-                       property->parent = klass;
-                       property->attrs = pb->attrs;
-                       property->name = mono_string_to_utf8 (pb->name);
-                       if (pb->get_method)
-                               property->get = inflate_method (type, (MonoObject *) pb->get_method);
-                       if (pb->set_method)
-                               property->set = inflate_method (type, (MonoObject *) pb->set_method);
-               } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) {
-                       *property = *((MonoReflectionProperty *) obj)->property;
-                       property->name = g_strdup (property->name);
-
-                       if (property->get)
-                               property->get = inflate_mono_method (klass, property->get, NULL);
-                       if (property->set)
-                               property->set = inflate_mono_method (klass, property->set, NULL);
-               } else
-                       g_assert_not_reached ();
-       }
-
-       for (i = 0; i < dgclass->count_events; i++) {
-               MonoObject *obj = mono_array_get (events, gpointer, i);
-               MonoEvent *event = &dgclass->events [i];
-
-               if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
-                       MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
-
-                       event->parent = klass;
-                       event->attrs = eb->attrs;
-                       event->name = mono_string_to_utf8 (eb->name);
-                       if (eb->add_method)
-                               event->add = inflate_method (type, (MonoObject *) eb->add_method);
-                       if (eb->remove_method)
-                               event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
-               } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
-                       *event = *((MonoReflectionMonoEvent *) obj)->event;
-                       event->name = g_strdup (event->name);
-
-                       if (event->add)
-                               event->add = inflate_mono_method (klass, event->add, NULL);
-                       if (event->remove)
-                               event->remove = inflate_mono_method (klass, event->remove, NULL);
-               } else
-                       g_assert_not_reached ();
-       }
-
        dgclass->initialized = TRUE;
 }
 
 static void
-ensure_generic_class_runtime_vtable (MonoClass *klass)
+fix_partial_generic_class (MonoClass *klass)
 {
        MonoClass *gklass = klass->generic_class->container_class;
+       MonoDynamicGenericClass *dgclass;
        int i;
 
        if (klass->wastypebuilder)
                return;
 
-       ensure_runtime_vtable (gklass);
+       dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
+
+       if (!dgclass->initialized)
+               return;
+
+       if (klass->method.count != gklass->method.count) {
+               klass->method.count = gklass->method.count;
+               klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+
+               for (i = 0; i < klass->method.count; i++) {
+                       klass->methods [i] = mono_class_inflate_generic_method_full (
+                               gklass->methods [i], klass, mono_class_get_context (klass));
+               }
+       }
+
+       if (klass->interface_count && klass->interface_count != gklass->interface_count) {
+               klass->interface_count = gklass->interface_count;
+               klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
+               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
 
-       klass->method.count = gklass->method.count;
-       klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+               for (i = 0; i < gklass->interface_count; ++i) {
+                       MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
+                       klass->interfaces [i] = mono_class_from_mono_type (iface_type);
+                       mono_metadata_free_type (iface_type);
 
-       for (i = 0; i < klass->method.count; i++) {
-               klass->methods [i] = mono_class_inflate_generic_method_full (
-                       gklass->methods [i], klass, mono_class_get_context (klass));
+                       ensure_runtime_vtable (klass->interfaces [i]);
+               }
+               klass->interfaces_inited = 1;
        }
 
-       klass->interface_count = gklass->interface_count;
-       klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
-       for (i = 0; i < klass->interface_count; ++i) {
-               MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
-               klass->interfaces [i] = mono_class_from_mono_type (iface_type);
-               mono_metadata_free_type (iface_type);
+       if (klass->field.count != gklass->field.count) {
+               klass->field.count = gklass->field.count;
+               klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
 
-               ensure_runtime_vtable (klass->interfaces [i]);
+               for (i = 0; i < klass->field.count; i++) {
+                       klass->fields [i] = gklass->fields [i];
+                       klass->fields [i].parent = klass;
+                       klass->fields [i].type = mono_class_inflate_generic_type (gklass->fields [i].type, mono_class_get_context (klass));
+               }
        }
-       klass->interfaces_inited = 1;
 
        /*We can only finish with this klass once it's parent has as well*/
        if (gklass->wastypebuilder)
@@ -10180,6 +10450,16 @@ ensure_generic_class_runtime_vtable (MonoClass *klass)
        return;
 }
 
+static void
+ensure_generic_class_runtime_vtable (MonoClass *klass)
+{
+       MonoClass *gklass = klass->generic_class->container_class;
+
+       ensure_runtime_vtable (gklass); 
+
+       fix_partial_generic_class (klass);
+}
+
 static void
 ensure_runtime_vtable (MonoClass *klass)
 {
@@ -10222,6 +10502,7 @@ ensure_runtime_vtable (MonoClass *klass)
                for (i = 0; i < klass->method.count; ++i)
                        klass->methods [i]->slot = i;
                
+               klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
                mono_class_setup_interface_offsets (klass);
                mono_class_setup_interface_id (klass);
        }
@@ -10292,7 +10573,7 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
 }
 
 static void
-typebuilder_setup_fields (MonoClass *klass)
+typebuilder_setup_fields (MonoClass *klass, MonoError *error)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionFieldBuilder *fb;
@@ -10305,6 +10586,8 @@ typebuilder_setup_fields (MonoClass *klass)
        klass->field.count = tb->num_fields;
        klass->field.first = 0;
 
+       mono_error_init (error);
+
        if (tb->class_size) {
                g_assert ((tb->packing_size & 0xfffffff0) == 0);
                klass->packing_size = tb->packing_size;
@@ -10323,7 +10606,9 @@ typebuilder_setup_fields (MonoClass *klass)
        for (i = 0; i < klass->field.count; ++i) {
                fb = mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
-               field->name = mono_string_to_utf8_image (image, fb->name);
+               field->name = mono_string_to_utf8_image (image, fb->name, error);
+               if (!mono_error_ok (error))
+                       return;
                if (fb->attrs) {
                        field->type = mono_metadata_type_dup (klass->image, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
                        field->type->attrs = fb->attrs;
@@ -10356,7 +10641,7 @@ typebuilder_setup_fields (MonoClass *klass)
 }
 
 static void
-typebuilder_setup_properties (MonoClass *klass)
+typebuilder_setup_properties (MonoClass *klass, MonoError *error)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionPropertyBuilder *pb;
@@ -10364,6 +10649,8 @@ typebuilder_setup_properties (MonoClass *klass)
        MonoProperty *properties;
        int i;
 
+       mono_error_init (error);
+
        if (!klass->ext)
                klass->ext = image_g_new0 (image, MonoClassExt, 1);
 
@@ -10376,7 +10663,9 @@ typebuilder_setup_properties (MonoClass *klass)
                pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
                properties [i].parent = klass;
                properties [i].attrs = pb->attrs;
-               properties [i].name = mono_string_to_utf8_image (image, pb->name);
+               properties [i].name = mono_string_to_utf8_image (image, pb->name, error);
+               if (!mono_error_ok (error))
+                       return;
                if (pb->get_method)
                        properties [i].get = pb->get_method->mhandle;
                if (pb->set_method)
@@ -10419,7 +10708,7 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
 }
 
 static void
-typebuilder_setup_events (MonoClass *klass)
+typebuilder_setup_events (MonoClass *klass, MonoError *error)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionEventBuilder *eb;
@@ -10427,6 +10716,8 @@ typebuilder_setup_events (MonoClass *klass)
        MonoEvent *events;
        int i, j;
 
+       mono_error_init (error);
+
        if (!klass->ext)
                klass->ext = image_g_new0 (image, MonoClassExt, 1);
 
@@ -10439,7 +10730,9 @@ typebuilder_setup_events (MonoClass *klass)
                eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
                events [i].parent = klass;
                events [i].attrs = eb->attrs;
-               events [i].name = mono_string_to_utf8_image (image, eb->name);
+               events [i].name = mono_string_to_utf8_image (image, eb->name, error);
+               if (!mono_error_ok (error))
+                       return;
                if (eb->add_method)
                        events [i].add = eb->add_method->mhandle;
                if (eb->remove_method)
@@ -10461,16 +10754,17 @@ typebuilder_setup_events (MonoClass *klass)
 }
 
 static gboolean
-remove_instantiations_of (gpointer key,
+remove_instantiations_of_and_ensure_contents (gpointer key,
                                                  gpointer value,
                                                  gpointer user_data)
 {
        MonoType *type = (MonoType*)key;
        MonoClass *klass = (MonoClass*)user_data;
 
-       if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass))
+       if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
+               fix_partial_generic_class (mono_class_from_mono_type (type)); //Ensure it's safe to use it.
                return TRUE;
-       else
+       else
                return FALSE;
 }
 
@@ -10489,6 +10783,7 @@ check_array_for_usertypes (MonoArray *arr)
 MonoReflectionType*
 mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 {
+       MonoError error;
        MonoClass *klass;
        MonoDomain* domain;
        MonoReflectionType* res;
@@ -10612,21 +10907,28 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        }
 
        /* FIXME: handle packing_size and instance_size */
-       typebuilder_setup_fields (klass);
+       typebuilder_setup_fields (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
+       typebuilder_setup_properties (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
 
-       typebuilder_setup_properties (klass);
+       typebuilder_setup_events (klass, &error);
+       if (!mono_error_ok (&error))
+               goto failure;
 
-       typebuilder_setup_events (klass);
-       
        klass->wastypebuilder = TRUE;
 
        /* 
         * If we are a generic TypeBuilder, there might be instantiations in the type cache
         * which have type System.Reflection.MonoGenericClass, but after the type is created, 
         * we want to return normal System.MonoType objects, so clear these out from the cache.
+        *
+        * Together with this we must ensure the contents of all instances to match the created type.
         */
        if (domain->type_hash && klass->generic_container)
-               mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of, klass);
+               mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, klass);
 
        mono_domain_unlock (domain);
        mono_loader_unlock ();
@@ -10640,6 +10942,14 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        g_assert (res != (MonoReflectionType*)tb);
 
        return res;
+
+failure:
+       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+       klass->wastypebuilder = TRUE;
+       mono_domain_unlock (domain);
+       mono_loader_unlock ();
+       mono_error_raise_exception (&error);
+       return NULL;
 }
 
 void
@@ -10932,7 +11242,7 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
 
        if (strcmp (obj->vtable->klass->name, "String") == 0) {
                result = mono_string_intern ((MonoString*)obj);
-               *handle_class = NULL;
+               *handle_class = mono_defaults.string_class;
                g_assert (result);
        } else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
@@ -11061,13 +11371,14 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                sig->explicit_this = helper->call_conv & 64 ? 1 : 0;
                sig->hasthis = helper->call_conv & 32 ? 1 : 0;
 
-               if (helper->call_conv == 0) /* unmanaged */
+               if (helper->unmanaged_call_conv) { /* unmanaged */
                        sig->call_convention = helper->unmanaged_call_conv - 1;
-               else
-                       if (helper->call_conv & 0x02)
-                               sig->call_convention = MONO_CALL_VARARG;
-               else
+                       sig->pinvoke = TRUE;
+               } else if (helper->call_conv & 0x02) {
+                       sig->call_convention = MONO_CALL_VARARG;
+               } else {
                        sig->call_convention = MONO_CALL_DEFAULT;
+               }
 
                sig->param_count = nargs;
                /* TODO: Copy type ? */
@@ -11101,12 +11412,20 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
                MonoClass *inflated;
                MonoType *type;
+               MonoClassField *field;
+
+               if (is_sre_field_builder (mono_object_class (f->fb)))
+                       field = ((MonoReflectionFieldBuilder*)f->fb)->handle;
+               else if (is_sr_mono_field (mono_object_class (f->fb)))
+                       field = ((MonoReflectionField*)f->fb)->field;
+               else
+                       g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
 
                type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context);
                inflated = mono_class_from_mono_type (type);
 
-               g_assert (f->fb->handle);
-               result = mono_class_get_field_from_name (inflated, mono_field_get_name (f->fb->handle));
+               result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
+               ensure_complete_type (field->parent);
                g_assert (result);
                mono_metadata_free_type (type);
                *handle_class = mono_defaults.fieldhandle_class;
@@ -11114,8 +11433,16 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
                MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)c->inst), context);
                MonoClass *inflated_klass = mono_class_from_mono_type (type);
-               g_assert (c->cb->mhandle);
-               result = inflate_mono_method (inflated_klass, c->cb->mhandle, (MonoObject*)c->cb);
+               MonoMethod *method;
+
+               if (is_sre_ctor_builder (mono_object_class (c->cb)))
+                       method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
+               else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
+                       method = ((MonoReflectionMethod *)c->cb)->method;
+               else
+                       g_error ("resolve_object:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (c->cb)));
+
+               result = inflate_mono_method (inflated_klass, method, (MonoObject*)c->cb);
                *handle_class = mono_defaults.methodhandle_class;
                mono_metadata_free_type (type);
        } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
@@ -11125,8 +11452,16 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                } 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);
-                       g_assert (m->mb->mhandle);
-                       result = inflate_mono_method (inflated_klass, m->mb->mhandle, (MonoObject*)m->mb);
+                       MonoMethod *method;
+
+                       if (is_sre_method_builder (mono_object_class (m->mb)))
+                               method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+                       else if (is_sr_mono_method (mono_object_class (m->mb)))
+                               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, method, (MonoObject*)m->mb);
                        mono_metadata_free_type (type);
                }
                *handle_class = mono_defaults.methodhandle_class;