New test.
[mono.git] / mono / metadata / reflection.c
index 631fbcd662e0850622405de57e4f7c5bd36c90cb..d3e026678cd7b632c24431f17a0c55a7c6d54c3e 100644 (file)
@@ -165,10 +165,11 @@ static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **h
 static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
 static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
-#endif
-
 static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
 static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
+static guint32 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb);
+#endif
+
 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
 static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
 static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
@@ -177,7 +178,6 @@ static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, gui
 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
-static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
 static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
 static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflectionType *type);
@@ -190,7 +190,12 @@ 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_generic_method (MonoClass *class);
+static gboolean is_sr_mono_generic_cmethod (MonoClass *class);
 static gboolean is_sr_mono_field (MonoClass *class);
+static gboolean is_sr_mono_property (MonoClass *class);
+static gboolean is_sre_method_on_tb_inst (MonoClass *class);
+static gboolean is_sre_ctor_on_tb_inst (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);
@@ -610,6 +615,36 @@ default_class_from_mono_type (MonoType *type)
 }
 #endif
 
+/*
+ * mono_class_get_ref_info:
+ *
+ *   Return the type builder/generic param builder corresponding to KLASS, if it exists.
+ */
+gpointer
+mono_class_get_ref_info (MonoClass *klass)
+{
+       if (klass->ref_info_handle == 0)
+               return NULL;
+       else
+               return mono_gchandle_get_target (klass->ref_info_handle);
+}
+
+void
+mono_class_set_ref_info (MonoClass *klass, gpointer obj)
+{
+       klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
+       g_assert (klass->ref_info_handle != 0);
+}
+
+void
+mono_class_free_ref_info (MonoClass *klass)
+{
+       if (klass->ref_info_handle) {
+               mono_gchandle_free (klass->ref_info_handle);
+               klass->ref_info_handle = 0;
+       }
+}
+
 static void
 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
 {
@@ -1402,6 +1437,7 @@ mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly
        }
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
 {
@@ -1474,7 +1510,6 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoRe
        rmb->refs = NULL;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
 static void
 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
 {
@@ -1539,6 +1574,7 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild
        values [MONO_METHODIMPL_DECLARATION] = tok;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
 {
@@ -1602,6 +1638,7 @@ mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, Mon
        mono_image_basic_method (&rmb, assembly);
        mb->table_idx = *rmb.table_idx;
 }
+#endif
 
 static char*
 type_get_fully_qualified_name (MonoType *type)
@@ -1982,6 +2019,7 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag
         * PROPERTY    (rows already preallocated in _get_type_info ())
         * METHOD      (method info already done with the generic method code)
         * METHODSEMANTICS
+        * CONSTANT
         */
        table = &assembly->tables [MONO_TABLE_PROPERTY];
        pb->table_idx = table->next_idx ++;
@@ -2012,6 +2050,17 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag
                values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
                values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
        }
+       if (pb->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT) {
+               guint32 field_type = 0;
+               table = &assembly->tables [MONO_TABLE_CONSTANT];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_CONSTANT_SIZE;
+               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PROPERTY | (pb->table_idx << MONO_HASCONSTANT_BITS);
+               values [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
+               values [MONO_CONSTANT_TYPE] = field_type;
+               values [MONO_CONSTANT_PADDING] = 0;
+       }
 }
 
 static void
@@ -2125,7 +2174,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        /* FIXME: track where gen_params should be freed and remove the GC root as well */
        MOVING_GC_REGISTER (&entry->gparam);
        entry->gparam = gparam;
-
+       
        g_ptr_array_add (assembly->gen_params, entry);
 }
 
@@ -2298,9 +2347,9 @@ mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboo
         */
        if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) && 
                        (type->type != MONO_TYPE_MVAR)) {
-               MonoReflectionTypeBuilder *tb = klass->reflection_info;
+               MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
                token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
-               mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
+               mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), mono_class_get_ref_info (klass));
                return token;
        }
 
@@ -2323,7 +2372,7 @@ mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboo
        token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
        g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
-       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
+       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), mono_class_get_ref_info (klass));
        return token;
 }
 
@@ -2337,21 +2386,13 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
-/*
- * Insert a memberef row into the metadata: the token that point to the memberref
- * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
- * mono_image_get_fieldref_token()).
- * The sig param is an index to an already built signature.
- */
 static guint32
-mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
+mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
 {
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, pclass;
-       guint32 parent;
 
-       parent = mono_image_typedef_or_ref (assembly, type);
        switch (parent & MONO_TYPEDEFORREF_MASK) {
        case MONO_TYPEDEFORREF_TYPEREF:
                pclass = MONO_MEMBERREF_PARENT_TYPEREF;
@@ -2385,6 +2426,20 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
        return token;
 }
 
+/*
+ * Insert a memberef row into the metadata: the token that point to the memberref
+ * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
+ * mono_image_get_fieldref_token()).
+ * The sig param is an index to an already built signature.
+ */
+static guint32
+mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
+{
+       guint32 parent = mono_image_typedef_or_ref (assembly, type);
+       return mono_image_add_memberef_row (assembly, parent, name, sig);
+}
+
+
 static guint32
 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
 {
@@ -2443,9 +2498,10 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method,
 static guint32
 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method)
 {
-       guint32 token;
+       guint32 token, parent, sig;
        ReflectionMethodBuilder rmb;
        char *name;
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
        
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
        if (token)
@@ -2460,8 +2516,15 @@ mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, Mo
        */
        if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG)
                rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT;
-       token = mono_image_get_memberref_token (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type),
-                                       name, method_builder_encode_signature (assembly, &rmb));
+
+       sig = method_builder_encode_signature (assembly, &rmb);
+
+       if (tb->generic_params)
+               parent = create_generic_typespec (assembly, tb);
+       else
+               parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type));
+
+       token = mono_image_add_memberef_row (assembly, parent, name, sig);
 
        g_free (name);
        g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
@@ -2561,38 +2624,43 @@ static guint32
 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec)
 {
        guint32 token;
-       
+
        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;
 }
 
 static guint32
 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *mb)
 {
-       guint32 token;
+       guint32 token, parent, sig;
        ReflectionMethodBuilder rmb;
        char *name;
+       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
        
-       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;
 
+       g_assert (tb->generic_params);
+
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
 
+       parent = create_generic_typespec (assembly, tb);
        name = mono_string_to_utf8 (rmb.name);
-       token = mono_image_get_memberref_token (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type),
-               name, method_builder_encode_signature (assembly, &rmb));
+       sig = method_builder_encode_signature (assembly, &rmb);
+
+       token = mono_image_add_memberef_row (assembly, parent, name, sig);
 
        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
@@ -2642,7 +2710,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);
@@ -2660,7 +2728,7 @@ 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, field->parent->image, type));
-       g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2674,7 +2742,7 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
        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;
        if (is_sre_field_builder (mono_object_class (f->fb))) {
@@ -2703,7 +2771,7 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
                g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
        }
 
-       g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token));
+       mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -2717,7 +2785,7 @@ mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCto
 
        /* 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;
 
@@ -2756,7 +2824,7 @@ mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCto
        }
 
 
-       g_hash_table_insert (assembly->handleref, c, GUINT_TO_POINTER (token));
+       mono_g_hash_table_insert (assembly->handleref_managed, c, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -2774,6 +2842,9 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI
 
        klass = method->klass;
 
+       if (m->method_args == NULL)
+               return method;
+
        if (method->is_inflated)
                method = ((MonoMethodInflated *) method)->declaring;
 
@@ -2812,7 +2883,7 @@ 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;
 
@@ -2848,7 +2919,7 @@ mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionM
                g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
        }
 
-       g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER (token));
+       mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
        return token;
 }
 
@@ -3078,7 +3149,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;
 
@@ -3113,7 +3184,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;
 }
@@ -3264,7 +3335,6 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        m->table_idx = am->token & 0xffffff;
        return am->token;
 }
-#endif
 
 /*
  * Insert into the metadata tables all the info about the TypeBuilder tb.
@@ -3428,6 +3498,7 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                }
        }
 }
+#endif
 
 static void
 collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
@@ -3684,29 +3755,32 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu
        }
 }
 
-static guint32
-add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass)
+static void
+add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
 {
        MonoDynamicTable *table;
        guint32 *values;
-       guint32 scope, idx, res, impl;
+       guint32 scope, scope_idx, impl, current_idx;
        gboolean forwarder = TRUE;
+       gpointer iter = NULL;
+       MonoClass *nested;
 
        if (klass->nested_in) {
-               impl = add_exported_type (assemblyb, assembly, klass->nested_in);
+               impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
                forwarder = FALSE;
        } else {
                scope = resolution_scope_from_image (assembly, klass->image);
                g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
-               idx = scope >> MONO_RESOLTION_SCOPE_BITS;
-               impl = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+               scope_idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+               impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
        }
 
        table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
 
        table->rows++;
        alloc_table (table, table->rows);
-       values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+       current_idx = table->next_idx;
+       values = table->values + current_idx * MONO_EXP_TYPE_SIZE;
 
        values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
        values [MONO_EXP_TYPE_TYPEDEF] = 0;
@@ -3714,11 +3788,10 @@ add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *a
        values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
        values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
 
-       res = (table->next_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
-
        table->next_idx++;
 
-       return res;
+       while ((nested = mono_class_get_nested_types (klass, &iter)))
+               add_exported_type (assemblyb, assembly, nested, current_idx);
 }
 
 static void
@@ -3741,7 +3814,7 @@ mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder
 
                klass = mono_class_from_mono_type (type);
 
-               add_exported_type (assemblyb, assembly, klass);
+               add_exported_type (assemblyb, assembly, klass, 0);
        }
 }
 
@@ -3986,13 +4059,8 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        *int32val = GUINT32_TO_LE (0); /* reserved */
        p += 4;
 
-       if (mono_framework_version () > 1) {
-               *p++ = 2; /* version */
-               *p++ = 0;
-       } else {
-               *p++ = 1; /* version */
-               *p++ = 0;
-       }
+       *p++ = 2; /* version */
+       *p++ = 0;
 
        if (meta->idx_string_wide)
                *p |= 0x01;
@@ -4948,6 +5016,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);
@@ -5010,6 +5079,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)
@@ -5125,6 +5196,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;
@@ -5656,10 +5728,7 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file)
        cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset);
        cli_header->ch_size = GUINT32_FROM_LE (72);
        cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
-       if (mono_framework_version () > 1)
-               cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
-       else 
-               cli_header->ch_runtime_minor = GUINT16_FROM_LE (0);
+       cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
        cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind);
        if (assemblyb->entry_point) {
                guint32 table_idx = 0;
@@ -6050,14 +6119,18 @@ mono_image_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflecti
 MonoReflectionAssembly*
 mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
 {
-       static MonoClass *System_Reflection_Assembly;
+       static MonoClass *assembly_type;
        MonoReflectionAssembly *res;
        
        CHECK_OBJECT (MonoReflectionAssembly *, assembly, NULL);
-       if (!System_Reflection_Assembly)
-               System_Reflection_Assembly = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "Assembly");
-       res = (MonoReflectionAssembly *)mono_object_new (domain, System_Reflection_Assembly);
+       if (!assembly_type) {
+               MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoAssembly");
+               if (class == NULL)
+                       class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Assembly");
+               g_assert (class);
+               assembly_type = class;
+       }
+       res = (MonoReflectionAssembly *)mono_object_new (domain, assembly_type);
        res->assembly = assembly;
 
        CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
@@ -6251,10 +6324,9 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
        MonoGenericInst *ginst;
        MonoArray *type_args;
        int i;
+       MonoObject *tb;
 
-
-       /*This will only be fixed once we do full managed inflate of system types*/
-       /*g_assert (!geninst->byref);*/
+       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 (
@@ -6274,9 +6346,10 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
 #endif
 
        res->type.type = geninst;
-       g_assert (gklass->reflection_info);
-       g_assert (!strcmp (((MonoObject*)gklass->reflection_info)->vtable->klass->name, "TypeBuilder"));
-       MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
+       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);
@@ -6378,13 +6451,32 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space"));
        }
 
-       if (klass->reflection_info && !klass->wastypebuilder) {
+       if (mono_class_get_ref_info (klass) && !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;
+                       return mono_class_get_ref_info (klass);
                }
        }
        // FIXME: Get rid of this, do it in the icalls for Type
@@ -6759,7 +6851,6 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        static MonoClass *System_Reflection_LocalVariableInfo = NULL;
        static MonoClass *System_Reflection_ExceptionHandlingClause = NULL;
        MonoReflectionMethodBody *ret;
-       MonoMethodNormal *mn;
        MonoMethodHeader *header;
        guint32 method_rva, local_var_sig_token;
     char *ptr;
@@ -6780,7 +6871,6 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
            (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
            (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
                return NULL;
-       mn = (MonoMethodNormal *)method;
        header = mono_method_get_header (method);
        
        /* Obtain local vars signature token */
@@ -6840,6 +6930,7 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        }
 
        CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
+       mono_metadata_free_mh (header);
        return ret;
 }
 
@@ -6936,7 +7027,7 @@ get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
        return;
 }
 
-static MonoObject *
+MonoObject *
 mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
 {
        void *retval;
@@ -7409,11 +7500,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 */
 
@@ -7602,13 +7694,15 @@ mono_reflection_get_token (MonoObject *obj)
                token = mono_class_get_event_token (p->event);
        } else if (strcmp (klass->name, "ParameterInfo") == 0) {
                MonoReflectionParameter *p = (MonoReflectionParameter*)obj;
+               MonoClass *member_class = mono_object_class (p->MemberImpl);
+               g_assert (mono_class_is_reflection_method_or_constructor (member_class));
 
                token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
        } else if (strcmp (klass->name, "Module") == 0) {
                MonoReflectionModule *m = (MonoReflectionModule*)obj;
 
                token = m->token;
-       } else if (strcmp (klass->name, "Assembly") == 0) {
+       } else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
                token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
        } else {
                gchar *msg = g_strdup_printf ("MetadataToken is not supported for type '%s.%s'", klass->name_space, klass->name);
@@ -8498,6 +8592,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);
@@ -8590,7 +8686,7 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                klass = mono_class_from_mono_type (type);
                cinfo = mono_custom_attrs_from_class (klass);
-       } else if (strcmp ("Assembly", klass->name) == 0) {
+       } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
                MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
                cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
        } else if (strcmp ("Module", klass->name) == 0) {
@@ -8613,8 +8709,44 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                cinfo = mono_custom_attrs_from_method (rmethod->method);
        } else if (strcmp ("ParameterInfo", klass->name) == 0) {
                MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
-               MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
-               cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+               MonoClass *member_class = mono_object_class (param->MemberImpl);
+               if (mono_class_is_reflection_method_or_constructor (member_class)) {
+                       MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
+                       cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+               } else if (is_sr_mono_property (member_class)) {
+                       MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
+                       MonoMethod *method;
+                       if (!(method = prop->property->get))
+                               method = prop->property->set;
+                       g_assert (method);
+
+                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+               } 
+#ifndef DISABLE_REFLECTION_EMIT
+               else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
+                       MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl);
+                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+               } else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
+                       MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
+                       MonoMethod *method = NULL;
+                       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 ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
+
+                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+               } 
+#endif
+               else {
+                       char *type_name = mono_type_get_full_name (member_class);
+                       char *msg = g_strdup_printf ("Custom attributes on a ParamInfo with member %s are not supported", type_name);
+                       MonoException *ex = mono_get_exception_not_supported  (msg);
+                       g_free (type_name);
+                       g_free (msg);
+                       mono_raise_exception (ex);
+               }
        } else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
                MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
                cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
@@ -8726,7 +8858,6 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
         return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
 
 static gboolean
 is_corlib_type (MonoClass *class)
@@ -8745,6 +8876,8 @@ is_corlib_type (MonoClass *class)
        return FALSE; \
 } while (0) \
 
+
+#ifndef DISABLE_REFLECTION_EMIT
 static gboolean
 is_sre_array (MonoClass *class)
 {
@@ -8794,24 +8927,17 @@ is_sre_field_builder (MonoClass *class)
 }
 
 static gboolean
-is_sr_mono_method (MonoClass *class)
+is_sre_method_on_tb_inst (MonoClass *class)
 {
-       check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
+       check_corlib_type_cached (class, "System.Reflection.Emit", "MethodOnTypeBuilderInst");
 }
 
 static gboolean
-is_sr_mono_cmethod (MonoClass *class)
+is_sre_ctor_on_tb_inst (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");
+       check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
 }
 
-
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref)
 {
@@ -8823,7 +8949,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;
        }
@@ -8867,6 +8994,10 @@ 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 (gclass->generic_type, count, types);
@@ -8893,20 +9024,24 @@ mono_reflection_register_with_runtime (MonoReflectionType *type)
 {
        MonoType *res = mono_reflection_type_get_handle (type);
        MonoDomain *domain = mono_object_domain ((MonoObject*)type);
-       MonoClass *class = mono_class_from_mono_type (res);
+       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)
+       if (!class->image->dynamic) {
                mono_class_setup_supertypes (class);
-
-       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);
-
+       } 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 ();
 }
@@ -8999,8 +9134,72 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
                *type = f->field->type;
        }
 }
+
+#else /* DISABLE_REFLECTION_EMIT */
+
+void
+mono_reflection_register_with_runtime (MonoReflectionType *type)
+{
+       /* This is empty */
+}
+
+static gboolean
+is_sre_type_builder (MonoClass *class)
+{
+       return FALSE;
+}
+
+static gboolean
+is_sre_generic_instance (MonoClass *class)
+{
+       return FALSE;
+}
+
 #endif /* !DISABLE_REFLECTION_EMIT */
 
+
+static gboolean
+is_sr_mono_field (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoField");
+}
+
+static gboolean
+is_sr_mono_property (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoProperty");
+}
+
+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_generic_method (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoGenericMethod");
+}
+
+static gboolean
+is_sr_mono_generic_cmethod (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoGenericCMethod");
+}
+
+gboolean
+mono_class_is_reflection_method_or_constructor (MonoClass *class)
+{
+       return is_sr_mono_method (class) || is_sr_mono_cmethod (class) || is_sr_mono_generic_method (class) || is_sr_mono_generic_cmethod (class);
+}
+
 static gboolean
 is_usertype (MonoReflectionType *ref)
 {
@@ -9472,10 +9671,9 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
        klass->element_class = klass;
 
-       if (klass->reflection_info == NULL) {
+       if (mono_class_get_ref_info (klass) == NULL) {
 
-               MOVING_GC_REGISTER (&klass->reflection_info);
-               klass->reflection_info = tb;
+               mono_class_set_ref_info (klass, tb);
 
                /* Put into cache so mono_class_get () will find it.
                Skip nested types as those should not be available on the global scope. */
@@ -9486,7 +9684,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                                g_slist_prepend (klass->image->reflection_info_unregister_classes, klass);
                }
        } else {
-               g_assert (klass->reflection_info == tb);
+               g_assert (mono_class_get_ref_info (klass) == tb);
        }
 
        mono_g_hash_table_insert (tb->module->dynamic_image->tokens,
@@ -9746,7 +9944,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 {
        MonoError error;
        MonoMethod *m;
-       MonoMethodNormal *pm;
+       MonoMethodWrapper *wrapperm;
        MonoMarshalSpec **specs;
        MonoReflectionMethodAux *method_aux;
        MonoImage *image;
@@ -9770,12 +9968,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
-       else if (rmb->refs)
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
        else
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodNormal, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
 
-       pm = (MonoMethodNormal*)m;
+       wrapperm = (MonoMethodWrapper*)m;
 
        m->dynamic = dynamic;
        m->slot = -1;
@@ -9785,6 +9981,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        g_assert (mono_error_ok (&error));
        m->klass = klass;
        m->signature = sig;
+       m->sre_method = TRUE;
        m->skip_visibility = rmb->skip_visibility;
        if (rmb->table_idx)
                m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
@@ -9864,22 +10061,22 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                 rmb->ilgen, num_clauses);
                }
 
-               pm->header = header;
+               wrapperm->header = header;
        }
 
        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);
@@ -10101,7 +10298,7 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
        }
 
        if (klass->wastypebuilder) {
-               tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
+               tb = (MonoReflectionTypeBuilder *) mono_class_get_ref_info (klass);
 
                is_dynamic = TRUE;
        }
@@ -10310,14 +10507,10 @@ 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);
 
@@ -10361,58 +10554,6 @@ 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 ((MonoReflectionType*)type, (MonoObject *) pb->get_method);
-                       if (pb->set_method)
-                               property->set = inflate_method ((MonoReflectionType*)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 ((MonoReflectionType*)type, (MonoObject *) eb->add_method);
-                       if (eb->remove_method)
-                               event->remove = inflate_method ((MonoReflectionType*)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;
 }
 
@@ -10486,7 +10627,7 @@ ensure_generic_class_runtime_vtable (MonoClass *klass)
 static void
 ensure_runtime_vtable (MonoClass *klass)
 {
-       MonoReflectionTypeBuilder *tb = klass->reflection_info;
+       MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
        int i, num, j;
 
        if (!klass->image->dynamic || (!tb && !klass->generic_class) || klass->wastypebuilder)
@@ -10553,12 +10694,12 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
 
        g_assert (klass->image->dynamic);
 
-       if (!klass->reflection_info)
+       if (!mono_class_get_ref_info (klass))
                return;
 
-       g_assert (strcmp (((MonoObject*)klass->reflection_info)->vtable->klass->name, "TypeBuilder") == 0);
+       g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);
 
-       tb = (MonoReflectionTypeBuilder*)klass->reflection_info;
+       tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);
 
        onum = 0;
        if (tb->methods) {
@@ -10598,7 +10739,7 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
 static void
 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
 {
-       MonoReflectionTypeBuilder *tb = klass->reflection_info;
+       MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
        MonoReflectionFieldBuilder *fb;
        MonoClassField *field;
        MonoImage *image = klass->image;
@@ -10625,6 +10766,14 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
        mono_class_alloc_ext (klass);
        klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
+       /*
+       This is, guess what, a hack.
+       The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash.
+       On the static path no field class is resolved, only types are built. This is the right thing to do
+       but we suck.
+       Setting size_inited is harmless because we're doing the same job as mono_class_setup_fields anyway.
+       */
+       klass->size_inited = 1;
 
        for (i = 0; i < klass->field.count; ++i) {
                fb = mono_array_get (tb->fields, gpointer, i);
@@ -10666,7 +10815,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
 static void
 typebuilder_setup_properties (MonoClass *klass, MonoError *error)
 {
-       MonoReflectionTypeBuilder *tb = klass->reflection_info;
+       MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
        MonoReflectionPropertyBuilder *pb;
        MonoImage *image = klass->image;
        MonoProperty *properties;
@@ -10703,7 +10852,6 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
 {
        MonoEvent *event = g_new0 (MonoEvent, 1);
        MonoClass *klass;
-       int j;
 
        klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
 
@@ -10717,7 +10865,9 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
        if (eb->raise_method)
                event->raise = eb->raise_method->mhandle;
 
+#ifndef MONO_SMALL_CONFIG
        if (eb->other_methods) {
+               int j;
                event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
                for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
                        MonoReflectionMethodBuilder *mb = 
@@ -10726,6 +10876,7 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
                        event->other [j] = mb->mhandle;
                }
        }
+#endif
 
        return mono_event_get_object (mono_object_domain (tb), klass, event);
 }
@@ -10733,11 +10884,11 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
 static void
 typebuilder_setup_events (MonoClass *klass, MonoError *error)
 {
-       MonoReflectionTypeBuilder *tb = klass->reflection_info;
+       MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
        MonoReflectionEventBuilder *eb;
        MonoImage *image = klass->image;
        MonoEvent *events;
-       int i, j;
+       int i;
 
        mono_error_init (error);
 
@@ -10763,7 +10914,9 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error)
                if (eb->raise_method)
                        events [i].raise = eb->raise_method->mhandle;
 
+#ifndef MONO_SMALL_CONFIG
                if (eb->other_methods) {
+                       int j;
                        events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
                        for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
                                MonoReflectionMethodBuilder *mb = 
@@ -10772,6 +10925,7 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error)
                                events [i].other [j] = mb->mhandle;
                        }
                }
+#endif
                mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
        }
 }
@@ -11016,8 +11170,7 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
 
        gparam->type.type = &pklass->byval_arg;
 
-       MOVING_GC_REGISTER (&pklass->reflection_info);
-       pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
+       mono_class_set_ref_info (pklass, gparam);
        mono_image_lock (image);
        image->reflection_info_unregister_classes = g_slist_prepend (image->reflection_info_unregister_classes, pklass);
        mono_image_unlock (image);
@@ -11239,8 +11392,8 @@ mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean
 static void
 ensure_complete_type (MonoClass *klass)
 {
-       if (klass->image->dynamic && !klass->wastypebuilder) {
-               MonoReflectionTypeBuilder *tb = klass->reflection_info;
+       if (klass->image->dynamic && !klass->wastypebuilder && mono_class_get_ref_info (klass)) {
+               MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
 
                mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
 
@@ -11394,13 +11547,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 ? */
@@ -11446,7 +11600,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context);
                inflated = mono_class_from_mono_type (type);
 
-               result = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
+               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;
@@ -11486,6 +11641,33 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                        mono_metadata_free_type (type);
                }
                *handle_class = mono_defaults.methodhandle_class;
+       } else if (strcmp (obj->vtable->klass->name, "MonoArrayMethod") == 0) {
+               MonoReflectionArrayMethod *m = (MonoReflectionArrayMethod*)obj;
+               MonoType *mtype;
+               MonoClass *klass;
+               MonoMethod *method;
+               gpointer iter;
+               char *name;
+
+               mtype = mono_reflection_type_get_handle (m->parent);
+               klass = mono_class_from_mono_type (mtype);
+
+               /* Find the method */
+
+               name = mono_string_to_utf8 (m->name);
+               iter = NULL;
+               while ((method = mono_class_get_methods (klass, &iter))) {
+                       if (!strcmp (method->name, name))
+                               break;
+               }
+               g_free (name);
+
+               // FIXME:
+               g_assert (method);
+               // FIXME: Check parameters/return value etc. match
+
+               result = method;
+               *handle_class = mono_defaults.methodhandle_class;
        } else if (is_sre_array (mono_object_get_class(obj)) ||
                                is_sre_byref (mono_object_get_class(obj)) ||
                                is_sre_pointer (mono_object_get_class(obj))) {
@@ -12099,14 +12281,14 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass)
 
        /* 
         * The result of mono_type_get_object () might be a System.MonoType but we
-        * need a TypeBuilder so use klass->reflection_info.
+        * need a TypeBuilder so use mono_class_get_ref_info (klass).
         */
-       g_assert (klass->reflection_info);
-       g_assert (!strcmp (((MonoObject*)(klass->reflection_info))->vtable->klass->name, "TypeBuilder"));
+       g_assert (mono_class_get_ref_info (klass));
+       g_assert (!strcmp (((MonoObject*)(mono_class_get_ref_info (klass)))->vtable->klass->name, "TypeBuilder"));
 
        params [0] = mono_type_get_object (mono_domain_get (), &oklass->byval_arg);
 
-       res = mono_runtime_invoke (method, (MonoObject*)(klass->reflection_info), params, &exc);
+       res = mono_runtime_invoke (method, (MonoObject*)(mono_class_get_ref_info (klass)), params, &exc);
        if (exc)
                return FALSE;
        else