2008-11-14 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / reflection.c
index 81e7a16349887c160298e2292941c9f7e794e05e..d1745fdda389edddb3ea31b874a3f5a310ac9aeb 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <config.h>
 #include "mono/utils/mono-digest.h"
+#include "mono/utils/mono-membar.h"
 #include "mono/metadata/reflection.h"
 #include "mono/metadata/tabledefs.h"
 #include "mono/metadata/metadata-internals.h"
@@ -31,9 +32,9 @@
 #include <ctype.h>
 #include "image.h"
 #include "cil-coff.h"
-#include "rawbuffer.h"
 #include "mono-endian.h"
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/mempool-internals.h>
 
 typedef struct {
        char *p;
@@ -137,7 +138,7 @@ static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder
 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 guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method);
-static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
 static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
@@ -151,6 +152,7 @@ static void get_default_param_value_blobs (MonoMethod *method, char **blobs, gui
 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 guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
 
 #define mono_reflection_lock() EnterCriticalSection (&reflection_mutex)
 #define mono_reflection_unlock() LeaveCriticalSection (&reflection_mutex)
@@ -820,12 +822,6 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
        int i;
 
        sigbuffer_init (&buf, 32);
-       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
-       idx = table->next_idx ++;
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
-
        sigbuffer_add_value (&buf, 0x07);
        sigbuffer_add_value (&buf, nl);
        for (i = 0; i < nl; ++i) {
@@ -839,8 +835,22 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
        sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
 
+       if (assembly->standalonesig_cache == NULL)
+               assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
+       idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
+       if (idx)
+               return idx;
+
+       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
+       idx = table->next_idx ++;
+       table->rows ++;
+       alloc_table (table, table->rows);
+       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+
        values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
 
+       g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
+
        return idx;
 }
 
@@ -863,7 +873,7 @@ method_count_clauses (MonoReflectionILGen *ilgen)
 }
 
 static MonoExceptionClause*
-method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
+method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
 {
        MonoExceptionClause *clauses;
        MonoExceptionClause *clause;
@@ -872,7 +882,7 @@ method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, g
        guint32 finally_start;
        int i, j, clause_index;;
 
-       clauses = g_new0 (MonoExceptionClause, num_clauses);
+       clauses = mp_g_new0 (mp, MonoExceptionClause, num_clauses);
 
        clause_index = 0;
        for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
@@ -1085,29 +1095,22 @@ find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32
        return 0;
 }
 
-/* protected by reflection_mutex: 
- * maps a mono runtime reflection handle to MonoCustomAttrInfo*
+/*
+ * LOCKING: Acquires the loader lock. 
  */
-static GHashTable *dynamic_custom_attrs = NULL;
-
 static MonoCustomAttrInfo*
-lookup_custom_attr (void *member)
+lookup_custom_attr (MonoImage *image, gpointer member)
 {
-       MonoCustomAttrInfo *ainfo, *res;
-       int size;
+       MonoCustomAttrInfo* res;
 
-       mono_reflection_lock ();
-       ainfo = g_hash_table_lookup (dynamic_custom_attrs, member);
-       mono_reflection_unlock ();
+       mono_loader_lock ();
+       res = mono_property_hash_lookup (image->property_hash, member, MONO_PROP_DYNAMIC_CATTR);
+       mono_loader_unlock ();
 
-       if (ainfo) {
-               /* Need to copy since it will be freed later */
-               size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
-               res = g_malloc0 (size);
-               memcpy (res, ainfo, size);
-               return res;
-       }
-       return NULL;
+       if (!res)
+               return NULL;
+
+       return g_memdup (res, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (res->num_attrs - MONO_ZERO_LEN_ARRAY));
 }
 
 static gboolean
@@ -1125,7 +1128,7 @@ custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
 }
 
 static MonoCustomAttrInfo*
-mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
+mono_custom_attrs_from_builders (MonoMemPool *mp, MonoImage *image, MonoArray *cattrs)
 {
        int i, index, count, not_visible;
        MonoCustomAttrInfo *ainfo;
@@ -1147,16 +1150,17 @@ mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
        }
        count -= not_visible;
 
-       ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
+       ainfo = mp_g_malloc0 (mp, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
 
        ainfo->image = image;
        ainfo->num_attrs = count;
+       ainfo->cached = mp != NULL;
        index = 0;
        mono_loader_lock ();
        for (i = 0; i < count; ++i) {
                cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
                if (custom_attr_visible (image, cattr)) {
-                       unsigned char *saved = mono_mempool_alloc (image->mempool, mono_array_length (cattr->data));
+                       unsigned char *saved = mono_image_alloc (image, mono_array_length (cattr->data));
                        memcpy (saved, mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
                        ainfo->attrs [index].ctor = cattr->ctor->method;
                        ainfo->attrs [index].data = saved;
@@ -1169,21 +1173,24 @@ mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
        return ainfo;
 }
 
+/*
+ * LOCKING: Acquires the loader lock. 
+ */
 static void
 mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
 {
-       MonoCustomAttrInfo *ainfo = mono_custom_attrs_from_builders (image, cattrs);
+       MonoCustomAttrInfo *ainfo, *tmp;
 
-       if (!ainfo)
+       if (!cattrs || !mono_array_length (cattrs))
                return;
 
-       mono_reflection_lock ();
-       if (!dynamic_custom_attrs)
-               dynamic_custom_attrs = g_hash_table_new (NULL, NULL);
-
-       g_hash_table_insert (dynamic_custom_attrs, obj, ainfo);
-       ainfo->cached = TRUE;
-       mono_reflection_unlock ();
+       ainfo = mono_custom_attrs_from_builders (image->mempool, image, cattrs);
+       mono_loader_lock ();
+       tmp = mono_property_hash_lookup (image->property_hash, obj, MONO_PROP_DYNAMIC_CATTR);
+       if (tmp)
+               mono_custom_attrs_free (tmp);
+       mono_property_hash_insert (image->property_hash, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
+       mono_loader_unlock ();
 }
 
 void
@@ -1596,7 +1603,7 @@ static guint32
 fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
 {
        SigBuffer buf;
-       guint32 idx;
+       guint32 idx, i;
 
        if (!assembly->save)
                return 0;
@@ -1605,6 +1612,16 @@ 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 (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);
+               }
+       }
        encode_type (assembly, type, &buf);
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
@@ -2347,6 +2364,34 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method)
        return token;
 }
 
+static guint32
+mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method)
+{
+       guint32 token;
+       ReflectionMethodBuilder rmb;
+       char *name;
+       
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+       if (token)
+               return token;
+
+       name = mono_string_to_utf8 (method->name);
+       reflection_methodbuilder_from_method_builder (&rmb, method);
+
+       /*
+        * A methodref signature can't contain an unmanaged calling convention.
+        * Since some flags are encoded as part of call_conv, we need to check against it.
+       */
+       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, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
+                                       name, method_builder_encode_signature (assembly, &rmb));
+
+       g_free (name);
+       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+       return token;
+}
+
 static guint32
 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
                                     const gchar *name, guint32 sig)
@@ -2372,19 +2417,83 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina
 }
 
 static guint32
-mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
+encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
+{
+       SigBuffer buf;
+       int i;
+       guint32 nparams = mono_array_length (mb->generic_params);
+       guint32 idx;
+
+       if (!assembly->save)
+               return 0;
+
+       sigbuffer_init (&buf, 32);
+
+       sigbuffer_add_value (&buf, 0xa);
+       sigbuffer_add_value (&buf, nparams);
+
+       for (i = 0; i < nparams; i++) {
+               sigbuffer_add_value (&buf, MONO_TYPE_MVAR);
+               sigbuffer_add_value (&buf, i);
+       }
+
+       idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+       sigbuffer_free (&buf);
+       return idx;
+}
+
+static guint32
+mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, mtoken = 0;
+
+       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb));
+       if (token)
+               return token;
+
+       table = &assembly->tables [MONO_TABLE_METHODSPEC];
+
+       mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb);
+       switch (mono_metadata_token_table (mtoken)) {
+       case MONO_TABLE_MEMBERREF:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
+               break;
+       case MONO_TABLE_METHOD:
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
+               values [MONO_METHODSPEC_METHOD] = mtoken;
+               values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_definition_sig (assembly, mb);
+       }
+
+       token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
+       table->next_idx ++;
+
+       mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token));
+       return token;
+}
+
+static guint32
+mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec)
 {
        guint32 token;
-       ReflectionMethodBuilder rmb;
        
+       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));
        if (token)
                return token;
 
-       reflection_methodbuilder_from_method_builder (&rmb, mb);
-       
-       token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
-               mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb));
+       token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb);
        g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
        return token;
 }
@@ -2394,6 +2503,7 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
 {
        guint32 token;
        ReflectionMethodBuilder rmb;
+       char *name;
        
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb));
        if (token)
@@ -2401,25 +2511,64 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
 
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
 
+       name = mono_string_to_utf8 (rmb.name);
        token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type,
-               mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb));
+               name, method_builder_encode_signature (assembly, &rmb));
+
+       g_free (name);
        g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
        return token;
 }
 
+static gboolean
+is_field_on_inst (MonoClassField *field)
+{
+       return (field->parent->generic_class && field->parent->generic_class->is_dynamic && ((MonoDynamicGenericClass*)field->parent->generic_class)->fields);
+}
+
+/*
+ * If FIELD is a field of a MonoDynamicGenericClass, return its non-inflated type.
+ */
+static MonoType*
+get_field_on_inst_generic_type (MonoClassField *field)
+{
+       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];
+}
+
 static guint32
 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
 {
        MonoType *type;
        guint32 token;
+       MonoClassField *field;
 
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
        if (token)
                return token;
        g_assert (f->field->parent);
-       type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type;
+
+       field = f->field;
+       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+               int index = field - field->parent->fields;
+               type = field->parent->generic_class->container_class->fields [index].type;
+       } else {
+               if (is_field_on_inst (f->field))
+                       type = get_field_on_inst_generic_type (f->field);
+               else
+                       type = f->field->type;
+       }
        token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg, 
-               f->field->name,  fieldref_encode_signature (assembly, type));
+                                                                                       mono_field_get_name (f->field),  
+                                                                                       fieldref_encode_signature (assembly, type));
        g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
        return token;
 }
@@ -2427,7 +2576,6 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
 static guint32
 mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f)
 {
-       MonoType *ftype;
        guint32 token;
        MonoClass *klass;
        MonoGenericClass *gclass;
@@ -2444,9 +2592,8 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
        dgclass = (MonoDynamicGenericClass *) gclass;
 
        name = mono_string_to_utf8 (fb->name);
-       ftype = mono_class_inflate_generic_type (fb->type->type, mono_generic_class_get_context ((gclass)));
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name,
-                                                                                       fieldref_encode_signature (assembly, ftype));
+       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));
        return token;
@@ -2492,7 +2639,6 @@ mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionM
        guint32 sig, token;
        MonoClass *klass;
        MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
        MonoReflectionMethodBuilder *mb = m->mb;
        ReflectionMethodBuilder rmb;
        char *name;
@@ -2507,7 +2653,6 @@ mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionM
        klass = mono_class_from_mono_type (m->inst->type.type);
        gclass = m->inst->type.type->data.generic_class;
        g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
 
        reflection_methodbuilder_from_method_builder (&rmb, mb);
 
@@ -2693,11 +2838,56 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
        return token;
 }
 
+/*
+ * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT.
+ */
+static MonoType*
+add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt)
+{
+       int i, count, len, pos;
+       MonoType *t;
+
+       count = 0;
+       if (modreq)
+               count += mono_array_length (modreq);
+       if (modopt)
+               count += mono_array_length (modopt);
+
+       if (count == 0)
+               return mono_metadata_type_dup (NULL, type);
+
+       len = sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod);
+       t = g_malloc (len);
+       memcpy (t, type, len);
+
+       t->num_mods = count;
+       pos = 0;
+       if (modreq) {
+               for (i = 0; i < mono_array_length (modreq); ++i) {
+                       MonoReflectionType *mod = mono_array_get (modreq, MonoReflectionType*, i);
+                       t->modifiers [pos].required = 1;
+                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+                       pos ++;
+               }
+       }
+       if (modopt) {
+               for (i = 0; i < mono_array_length (modopt); ++i) {
+                       MonoReflectionType *mod = mono_array_get (modopt, MonoReflectionType*, i);
+                       t->modifiers [pos].required = 0;
+                       t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+                       pos ++;
+               }
+       }
+
+       return t;
+}
+
 static guint32
 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
 {
        MonoDynamicTable *table;
        MonoClass *klass;
+       MonoType *custom = NULL;
        guint32 *values;
        guint32 token, pclass, parent, sig;
        gchar *name;
@@ -2709,7 +2899,15 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        klass = mono_class_from_mono_type (fb->typeb->type);
        name = mono_string_to_utf8 (fb->name);
 
-       sig = fieldref_encode_signature (assembly, fb->type->type);
+       /* fb->type does not include the custom modifiers */
+       /* FIXME: We should do this in one place when a fieldbuilder is created */
+       if (fb->modreq || fb->modopt) {
+               custom = add_custom_modifiers (assembly, fb->type->type, fb->modreq, fb->modopt);
+               sig = fieldref_encode_signature (assembly, custom);
+               g_free (custom);
+       } else {
+               sig = fieldref_encode_signature (assembly, fb->type->type);
+       }
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
        g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
@@ -2730,6 +2928,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));
+       g_free (name);
        return token;
 }
 
@@ -3330,6 +3529,8 @@ mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder
                        values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
                        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);
+
+                       table->next_idx++;
                }
        }
 }
@@ -3410,6 +3611,19 @@ compare_declsecurity_attrs (const void *a, const void *b)
        return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
 }
 
+static int
+compare_interface_impl (const void *a, const void *b)
+{
+       const guint32 *a_values = a;
+       const guint32 *b_values = b;
+
+       int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS];
+       if (klass)
+               return klass;
+
+       return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE];
+}
+
 static void
 pad_heap (MonoDynamicStream *sh)
 {
@@ -3472,7 +3686,8 @@ build_compressed_metadata (MonoDynamicImage *assembly)
                | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
                | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
                | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
-               | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM);
+               | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM)
+               | ((guint64)1 << MONO_TABLE_INTERFACEIMPL);
        
        /* Compute table sizes */
        /* the MonoImage has already been created in mono_image_basic_init() */
@@ -3561,7 +3776,7 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        *int32val = GUINT32_TO_LE (0); /* reserved */
        p += 4;
 
-       if (mono_get_runtime_info ()->framework_version [0] > '1') {
+       if (mono_framework_version () > 1) {
                *p++ = 2; /* version */
                *p++ = 0;
        } else {
@@ -3609,6 +3824,9 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        table = &assembly->tables [MONO_TABLE_DECLSECURITY];
        if (table->rows)
                qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs);
+       table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
+       if (table->rows)
+               qsort (table->values + MONO_INTERFACEIMPL_SIZE, table->rows, sizeof (guint32) * MONO_INTERFACEIMPL_SIZE, compare_interface_impl);
 
        /* compress the tables */
        for (i = 0; i < MONO_TABLE_NUM; i++){
@@ -3727,7 +3945,7 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                                continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
                                MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
-                               g_assert (f->generic_info);
+                               g_assert (is_field_on_inst (f));
                                continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") ||
                                        !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
@@ -3747,6 +3965,8 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                                MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
                                g_assert (mono_method_signature (m)->generic_param_count);
                                continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
+                               continue;
                        } else {
                                g_assert_not_reached ();
                        }
@@ -4018,6 +4238,8 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
        }               
 }
 
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+
 /*
  * mono_image_build_metadata() will fill the info in all the needed metadata tables
  * for the modulebuilder @moduleb.
@@ -4167,6 +4389,18 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
        fixup_cattrs (assembly);
 }
 
+#else /* DISABLE_REFLECTION_EMIT_SAVE */
+
+void
+mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
+{
+       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit_save, so saving of dynamic assemblies is not supported.");
+}
+
+#endif /* DISABLE_REFLECTION_EMIT_SAVE */
+
+#ifndef DISABLE_REFLECTION_EMIT
+
 /*
  * mono_image_insert_string:
  * @module: module builder object
@@ -4262,7 +4496,8 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                ReflectionMethodBuilder rmb;
                guint32 parent, sig;
-       
+               char *name;
+
                reflection_methodbuilder_from_method_builder (&rmb, mb);
                rmb.opt_types = opt_param_types;
 
@@ -4274,8 +4509,10 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
                parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
                parent |= MONO_MEMBERREF_PARENT_METHODDEF;
 
+               name = mono_string_to_utf8 (rmb.name);
                token = mono_image_get_varargs_method_token (
-                       assembly, parent, mono_string_to_utf8 (rmb.name), sig);
+                       assembly, parent, name, sig);
+               g_free (name);
        } else {
                g_error ("requested method token for %s\n", klass->name);
        }
@@ -4306,10 +4543,10 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
 
-               if (tb->module->dynamic_image == assembly && !tb->generic_params)
+               if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
                        token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
                else
-                       token = mono_image_get_methodbuilder_token (assembly, mb);
+                       token = mono_image_get_methodbuilder_token (assembly, mb, create_methodspec);
                /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
        } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
                MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
@@ -4378,7 +4615,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
        } else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField *)obj;
-               if ((f->field->parent->image == &assembly->image) && !f->field->generic_info) {
+               if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) {
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
@@ -4433,6 +4670,8 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject
        }
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 typedef struct {
        guint32 import_lookup_table;
        guint32 timestamp;
@@ -4455,7 +4694,12 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        MonoDynamicImage *image;
        int i;
 
-       const char *version = mono_get_runtime_info ()->runtime_version;
+       const char *version;
+
+       if (!strcmp (mono_get_runtime_info ()->framework_version, "2.1"))
+               version = "v2.0.50727"; /* HACK: SL 2 enforces the .net 2 metadata version */
+       else
+               version = mono_get_runtime_info ()->runtime_version;
 
 #if HAVE_BOEHM_GC
        image = GC_MALLOC (sizeof (MonoDynamicImage));
@@ -4487,6 +4731,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->handleref = g_hash_table_new (NULL, NULL);
        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 (NULL, NULL, MONO_HASH_KEY_GC);
        image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
@@ -4534,8 +4779,11 @@ void
 mono_dynamic_image_free (MonoDynamicImage *image)
 {
        MonoDynamicImage *di = image;
+       GList *list;
        int i;
 
+       if (di->methodspec)
+               mono_g_hash_table_destroy (di->methodspec);
        if (di->typespec)
                g_hash_table_destroy (di->typespec);
        if (di->typeref)
@@ -4550,9 +4798,28 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL);
                g_hash_table_destroy (di->blob_cache);
        }
+       if (di->standalonesig_cache)
+               g_hash_table_destroy (di->standalonesig_cache);
+       for (list = di->array_methods; list; list = list->next) {
+               ArrayMethod *am = (ArrayMethod *)list->data;
+               g_free (am->sig);
+               g_free (am->name);
+               g_free (am);
+       }
        g_list_free (di->array_methods);
-       if (di->gen_params)
-               g_ptr_array_free (di->gen_params, TRUE);
+       if (di->gen_params) {
+               for (i = 0; i < di->gen_params->len; i++) {
+                       GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
+                       if (entry->gparam->type.type) {
+                               MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
+                               g_free ((char*)param->name);
+                               g_free (param);
+                               g_free (entry->gparam->type.type);
+                       }
+                       g_free (entry);
+               }
+               g_ptr_array_free (di->gen_params, TRUE);
+       }
        if (di->token_fixups)
                mono_g_hash_table_destroy (di->token_fixups);
        if (di->method_to_table_idx)
@@ -4563,6 +4830,9 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                g_hash_table_destroy (di->method_aux_hash);
        g_free (di->strong_name);
        g_free (di->win32_res);
+       if (di->public_key)
+               g_free (di->public_key);
+
        /*g_print ("string heap destroy for image %p\n", di);*/
        mono_dynamic_stream_reset (&di->sheap);
        mono_dynamic_stream_reset (&di->code);
@@ -4576,6 +4846,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
        }
 }      
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 /*
  * mono_image_basic_init:
  * @assembly: an assembly builder object
@@ -4650,6 +4922,8 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
        mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 static int
 calc_section_size (MonoDynamicImage *assembly)
 {
@@ -4776,6 +5050,7 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
        MonoPEResourceDirEntry dir_entry;
        MonoPEResourceDataEntry data_entry;
        GSList *l;
+       guint32 res_id_entries;
 
        /*
         * For the format of the resource directory, see the article
@@ -4794,32 +5069,35 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
        node->offset = p - begin;
 
        /* IMAGE_RESOURCE_DIRECTORY */
-       dir.res_id_entries = GUINT32_TO_LE (g_slist_length (node->children));
+       res_id_entries = g_slist_length (node->children);
+       dir.res_id_entries = GUINT16_TO_LE (res_id_entries);
 
        memcpy (p, &dir, sizeof (dir));
        p += sizeof (dir);
 
        /* Reserve space for entries */
        entries = p;
-       p += sizeof (dir_entry) * dir.res_id_entries;
+       p += sizeof (dir_entry) * res_id_entries;
 
        /* Write children */
        for (l = node->children; l; l = l->next) {
                ResTreeNode *child = (ResTreeNode*)l->data;
 
                if (child->win32_res) {
+                       guint32 size;
 
                        child->offset = p - begin;
 
                        /* IMAGE_RESOURCE_DATA_ENTRY */
                        data_entry.rde_data_offset = GUINT32_TO_LE (p - begin + sizeof (data_entry));
-                       data_entry.rde_size = mono_array_length (child->win32_res->res_data);
+                       size = mono_array_length (child->win32_res->res_data);
+                       data_entry.rde_size = GUINT32_TO_LE (size);
 
                        memcpy (p, &data_entry, sizeof (data_entry));
                        p += sizeof (data_entry);
 
-                       memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), data_entry.rde_size);
-                       p += data_entry.rde_size;
+                       memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), size);
+                       p += size;
                } else {
                        resource_tree_encode (child, begin, p, &p);
                }
@@ -4828,10 +5106,9 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
        /* IMAGE_RESOURCE_ENTRY */
        for (l = node->children; l; l = l->next) {
                ResTreeNode *child = (ResTreeNode*)l->data;
-               dir_entry.name_offset = GUINT32_TO_LE (child->id);
 
-               dir_entry.is_dir = child->win32_res ? 0 : 1;
-               dir_entry.dir_offset = GUINT32_TO_LE (child->offset);
+               MONO_PE_RES_DIR_ENTRY_SET_NAME (dir_entry, FALSE, child->id);
+               MONO_PE_RES_DIR_ENTRY_SET_DIR (dir_entry, !child->win32_res, child->offset);
 
                memcpy (entries, &dir_entry, sizeof (dir_entry));
                entries += sizeof (dir_entry);
@@ -4840,6 +5117,16 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf)
        *endbuf = p;
 }
 
+static void
+resource_tree_free (ResTreeNode * node)
+{
+       GSList * list;
+       for (list = node->children; list; list = list->next)
+               resource_tree_free ((ResTreeNode*)list->data);
+       g_slist_free(node->children);
+       g_free (node);
+}
+
 static void
 assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssemblyBuilder *assemblyb)
 {
@@ -4881,6 +5168,7 @@ assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssembly
        memcpy (assembly->win32_res, buf, p - buf);
 
        g_free (buf);
+       resource_tree_free (tree);
 }
 
 static void
@@ -4890,10 +5178,10 @@ fixup_resource_directory (char *res_section, char *p, guint32 rva)
        int i;
 
        p += sizeof (MonoPEResourceDir);
-       for (i = 0; i < dir->res_named_entries + dir->res_id_entries; ++i) {
+       for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) {
                MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
-               char *child = res_section + (GUINT32_FROM_LE (dir_entry->dir_offset));
-               if (dir_entry->is_dir) {
+               char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry);
+               if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) {
                        fixup_resource_directory (res_section, child, rva);
                } else {
                        MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
@@ -4912,6 +5200,8 @@ checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
                g_error ("WriteFile returned %d\n", GetLastError ());
 }
 
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+
 /*
  * mono_image_create_pefile:
  * @mb: a module builder object
@@ -4920,7 +5210,8 @@ checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
  * assembly->pefile where it can be easily retrieved later in chunks.
  */
 void
-mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) {
+mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file)
+{
        MonoMSDOSHeader *msdos;
        MonoDotNetHeader *header;
        MonoSectionTable *section;
@@ -5138,7 +5429,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_get_runtime_info ()->framework_version [0] > '1')
+       if (mono_framework_version () > 1)
                cli_header->ch_runtime_minor = GUINT16_FROM_LE (5);
        else 
                cli_header->ch_runtime_minor = GUINT16_FROM_LE (0);
@@ -5272,6 +5563,18 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) {
        assembly->blob_cache = NULL;
 }
 
+#else /* DISABLE_REFLECTION_EMIT_SAVE */
+
+void
+mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file)
+{
+       g_assert_not_reached ();
+}
+
+#endif /* DISABLE_REFLECTION_EMIT_SAVE */
+
+#ifndef DISABLE_REFLECTION_EMIT
+
 MonoReflectionModule *
 mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
 {
@@ -5327,6 +5630,8 @@ mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *f
        return mono_module_get_object (mono_domain_get (), image);
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 /*
  * We need to return always the same object for MethodInfo, FieldInfo etc..
  * but we need to consider the reflected type.
@@ -5407,6 +5712,8 @@ register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynam
        CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 void
 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
 {
@@ -5444,6 +5751,8 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
        }
 }
 
+#endif
+
 /*
  * mono_assembly_get_object:
  * @domain: an app domain
@@ -5721,6 +6030,30 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        MonoReflectionType *res;
        MonoClass *klass = mono_class_from_mono_type (type);
 
+       /*we must avoid using @type as it might have come
+        * from a mono_metadata_type_dup and the caller
+        * expects that is can be freed.
+        * Using the right type from 
+        */
+       type = klass->byval_arg.byref == type->byref ? &klass->byval_arg : &klass->this_arg;
+
+       /* void is very common */
+       if (type->type == MONO_TYPE_VOID && domain->typeof_void)
+               return (MonoReflectionType*)domain->typeof_void;
+
+       /*
+        * If the vtable of the given class was already created, we can use
+        * the MonoType from there and avoid all locking and hash table lookups.
+        * 
+        * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects
+        * that the resulting object is diferent.   
+        */
+       if (type == &klass->byval_arg && !klass->image->dynamic) {
+               MonoVTable *vtable = mono_class_try_get_vtable (domain, klass);
+               if (vtable && vtable->type)
+                       return vtable->type;
+       }
+
        mono_domain_lock (domain);
        if (!domain->type_hash)
                domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
@@ -5759,6 +6092,10 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
 #endif
        res->type = type;
        mono_g_hash_table_insert (domain->type_hash, type, res);
+
+       if (type->type == MONO_TYPE_VOID)
+               MONO_OBJECT_SETREF (domain, typeof_void, res);
+
        mono_domain_unlock (domain);
        return res;
 }
@@ -5785,6 +6122,13 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
        MonoClass *klass;
        MonoReflectionMethod *ret;
 
+       /*
+        * Don't let static RGCTX invoke wrappers get into
+        * MonoReflectionMethods.
+        */
+       if (method->wrapper_type == MONO_WRAPPER_STATIC_RGCTX_INVOKE)
+               method = mono_marshal_method_from_wrapper (method);
+
        if (method->is_inflated) {
                MonoReflectionGenericMethod *gret;
 
@@ -5847,9 +6191,9 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res = (MonoReflectionField *)mono_object_new (domain, monofield_klass);
        res->klass = klass;
        res->field = field;
-       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
-       if (field->generic_info)
-               res->attrs = field->generic_info->generic_type->attrs;
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
+       if (is_field_on_inst (field))
+               res->attrs = get_field_on_inst_generic_type (field)->attrs;
        else
                res->attrs = field->type->attrs;
        MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
@@ -5960,6 +6304,7 @@ MonoArray*
 mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
 {
        static MonoClass *System_Reflection_ParameterInfo;
+       static MonoClass *System_Reflection_ParameterInfo_array;
        MonoArray *res = NULL;
        MonoReflectionMethod *member = NULL;
        MonoReflectionParameter *param = NULL;
@@ -5970,14 +6315,23 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        MonoObject *missing = NULL;
        MonoMarshalSpec **mspecs;
        MonoMethodSignature *sig;
+       MonoVTable *pinfo_vtable;
        int i;
 
-       if (!System_Reflection_ParameterInfo)
-               System_Reflection_ParameterInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "ParameterInfo");
+       if (!System_Reflection_ParameterInfo_array) {
+               MonoClass *klass;
+
+               klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "ParameterInfo");
+               mono_memory_barrier ();
+               System_Reflection_ParameterInfo = klass; 
+       
+               klass = mono_array_class_get (klass, 1);
+               mono_memory_barrier ();
+               System_Reflection_ParameterInfo_array = klass;
+       }
        
        if (!mono_method_signature (method)->param_count)
-               return mono_array_new (domain, System_Reflection_ParameterInfo, 0);
+               return mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0);
 
        /* Note: the cache is based on the address of the signature into the method
         * since we already cache MethodInfos with the method as keys.
@@ -5992,9 +6346,10 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
        mono_method_get_marshal_info (method, mspecs);
 
-       res = mono_array_new (domain, System_Reflection_ParameterInfo, sig->param_count);
+       res = mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count);
+       pinfo_vtable = mono_class_vtable (domain, System_Reflection_ParameterInfo);
        for (i = 0; i < sig->param_count; ++i) {
-               param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo);
+               param = (MonoReflectionParameter *)mono_object_new_specific (pinfo_vtable);
                MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, sig->params [i]));
                MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
                MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
@@ -6592,6 +6947,12 @@ _mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image,
 
        if (info->assembly.name) {
                MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
+               if (!assembly && image && image->assembly && mono_assembly_names_equal (&info->assembly, &image->assembly->aname))
+                       /* 
+                        * This could happen in the AOT compiler case when the search hook is not
+                        * installed.
+                        */
+                       assembly = image->assembly;
                if (!assembly) {
                        /* then we must load the assembly ourselve - see #60439 */
                        assembly = mono_assembly_load (&info->assembly, NULL, NULL);
@@ -6630,13 +6991,13 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
        if (!klass)
                return NULL;
        for (mod = info->nested; mod; mod = mod->next) {
-               GList *nested;
+               gpointer iter = NULL;
+               MonoClass *parent;
 
-               mono_class_init (klass);
-               nested = klass->nested_classes;
-               klass = NULL;
-               while (nested) {
-                       klass = nested->data;
+               parent = klass;
+               mono_class_init (parent);
+
+               while ((klass = mono_class_get_nested_types (parent, &iter))) {
                        if (ignorecase) {
                                if (g_strcasecmp (klass->name, mod->data) == 0)
                                        break;
@@ -6644,8 +7005,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
                                if (strcmp (klass->name, mod->data) == 0)
                                        break;
                        }
-                       klass = NULL;
-                       nested = nested->next;
                }
                if (!klass)
                        break;
@@ -6891,9 +7250,15 @@ mono_reflection_get_token (MonoObject *obj)
        } else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField*)obj;
 
-               if (f->field->generic_info && f->field->generic_info->reflection_info)
-                       return mono_reflection_get_token (f->field->generic_info->reflection_info);
+               if (is_field_on_inst (f->field)) {
+                       MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass*)f->field->parent->generic_class;
+                       int field_index = f->field - dgclass->fields;
+                       MonoObject *obj;
 
+                       g_assert (field_index >= 0 && field_index < dgclass->count_fields);
+                       obj = dgclass->field_objects [field_index];
+                       return mono_reflection_get_token (obj);
+               }
                token = mono_class_get_field_token (f->field);
        } else if (strcmp (klass->name, "MonoProperty") == 0) {
                MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
@@ -7585,7 +7950,6 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_method (MonoMethod *method)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
 
        /*
@@ -7597,8 +7961,9 @@ mono_custom_attrs_from_method (MonoMethod *method)
        if (method->is_inflated)
                method = ((MonoMethodInflated *) method)->declaring;
        
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (method)))
-               return cinfo;
+       if (method->dynamic || method->klass->image->dynamic)
+               return lookup_custom_attr (method->klass->image, method);
+
        idx = mono_method_get_index (method);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_METHODDEF;
@@ -7608,14 +7973,14 @@ mono_custom_attrs_from_method (MonoMethod *method)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_class (MonoClass *klass)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
 
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
-       
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (klass)))
-               return cinfo;
+
+       if (klass->image->dynamic)
+               return lookup_custom_attr (klass->image, klass);
+
        if (klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR) {
                idx = mono_metadata_token_index (klass->sizes.generic_param_token);
                idx <<= MONO_CUSTOM_ATTR_BITS;
@@ -7631,11 +7996,10 @@ mono_custom_attrs_from_class (MonoClass *klass)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_assembly (MonoAssembly *assembly)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
        
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (assembly)))
-               return cinfo;
+       if (assembly->image->dynamic)
+               return lookup_custom_attr (assembly->image, assembly);
        idx = 1; /* there is only one assembly */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
@@ -7645,11 +8009,10 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly)
 static MonoCustomAttrInfo*
 mono_custom_attrs_from_module (MonoImage *image)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
        
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (image)))
-               return cinfo;
+       if (image->dynamic)
+               return lookup_custom_attr (image, image);
        idx = 1; /* there is only one module */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_MODULE;
@@ -7659,11 +8022,12 @@ mono_custom_attrs_from_module (MonoImage *image)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
        
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (property)))
-               return cinfo;
+       if (klass->image->dynamic) {
+               property = mono_metadata_get_corresponding_property_from_generic_type_definition (property);
+               return lookup_custom_attr (klass->image, property);
+       }
        idx = find_property_index (klass, property);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_PROPERTY;
@@ -7673,11 +8037,12 @@ mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
        
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (event)))
-               return cinfo;
+       if (klass->image->dynamic) {
+               event = mono_metadata_get_corresponding_event_from_generic_type_definition (event);
+               return lookup_custom_attr (klass->image, event);
+       }
        idx = find_event_index (klass, event);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_EVENT;
@@ -7687,11 +8052,11 @@ mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
 MonoCustomAttrInfo*
 mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
 {
-       MonoCustomAttrInfo *cinfo;
        guint32 idx;
-       
-       if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (field)))
-               return cinfo;
+       if (klass->image->dynamic) {
+               field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
+               return lookup_custom_attr (klass->image, field);
+       }
        idx = find_field_index (klass, field);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_FIELDDEF;
@@ -7843,22 +8208,22 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
        } else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
                MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (assemblyb->assembly.assembly->image, assemblyb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
        } else if (strcmp ("TypeBuilder", klass->name) == 0) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (&tb->module->dynamic_image->image, tb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs);
        } else if (strcmp ("ModuleBuilder", klass->name) == 0) {
                MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (&mb->dynamic_image->image, mb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs);
        } else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
                MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (cb->mhandle->klass->image, cb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs);
        } else if (strcmp ("MethodBuilder", klass->name) == 0) {
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (mb->mhandle->klass->image, mb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs);
        } else if (strcmp ("FieldBuilder", klass->name) == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
-               cinfo = mono_custom_attrs_from_builders (&((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
+               cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
        } else if (strcmp ("MonoGenericClass", klass->name) == 0) {
                MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
                cinfo = mono_reflection_get_custom_attrs_info ((MonoObject*)gclass->generic_type);
@@ -8051,7 +8416,7 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
                *type = fb->type->type;
        } else {
                MonoReflectionField *f = (MonoReflectionField *)field;
-               *name = g_strdup (f->field->name);
+               *name = g_strdup (mono_field_get_name (f->field));
                *type = f->field->type;
        }
 }
@@ -8371,6 +8736,8 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char
        *retbuffer = buffer;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 /*
  * mono_reflection_get_custom_attrs_blob:
  * @ctor: custom attribute constructor
@@ -8512,7 +8879,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                return;
        }
 
-       klass = mono_mempool_alloc0 (tb->module->dynamic_image->image.mempool, sizeof (MonoClass));
+       klass = mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
 
        klass->image = &tb->module->dynamic_image->image;
 
@@ -8592,7 +8959,7 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
        if (tb->generic_container)
                return;
 
-       tb->generic_container = g_new0 (MonoGenericContainer, 1);
+       tb->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
        tb->generic_container->owner.klass = klass;
 }
 
@@ -8619,11 +8986,11 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
 
        g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
 
-       klass->generic_container = mono_mempool_alloc0 (klass->image->mempool, sizeof (MonoGenericContainer));
+       klass->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
 
        klass->generic_container->owner.klass = klass;
        klass->generic_container->type_argc = count;
-       klass->generic_container->type_params = mono_mempool_alloc0 (klass->image->mempool, sizeof (MonoGenericParam) * count);
+       klass->generic_container->type_params = mono_image_alloc0 (klass->image, sizeof (MonoGenericParam) * count);
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
@@ -8689,13 +9056,15 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
        mono_loader_unlock ();
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 static MonoMarshalSpec*
-mono_marshal_spec_from_builder (MonoAssembly *assembly,
+mono_marshal_spec_from_builder (MonoMemPool *mp, MonoAssembly *assembly,
                                                                MonoReflectionMarshal *minfo)
 {
        MonoMarshalSpec *res;
 
-       res = g_new0 (MonoMarshalSpec, 1);
+       res = mp_g_new0 (mp, MonoMarshalSpec, 1);
        res->native = minfo->type;
 
        switch (minfo->type) {
@@ -8836,7 +9205,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
                m->signature->pinvoke = 1;
 
-               method_aux = g_new0 (MonoReflectionMethodAux, 1);
+               method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
 
                method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_mp (mp, rmb->dllentry) : mono_mempool_strdup (mp, m->name);
                method_aux->dll = mono_string_to_utf8_mp (mp, rmb->dll);
@@ -8898,7 +9267,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
                header->num_clauses = num_clauses;
                if (num_clauses) {
-                       header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image,
+                       header->clauses = method_encode_clauses (mp, (MonoDynamicImage*)klass->image,
                                 rmb->ilgen, num_clauses);
                }
 
@@ -8909,9 +9278,13 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                int count = mono_array_length (rmb->generic_params);
                MonoGenericContainer *container;
 
-               m->generic_container = container = rmb->generic_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 = g_new0 (MonoGenericParam, count);
+               container->type_params = mp_g_new0 (mp, MonoGenericParam, count);
                container->owner.method = m;
 
                for (i = 0; i < count; i++) {
@@ -8953,8 +9326,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
                                if ((i > 0) && (pb->attrs)) {
                                        /* Make a copy since it might point to a shared type structure */
-                                       /* FIXME: Alloc this from a mempool */
-                                       m->signature->params [i - 1] = mono_metadata_type_dup (NULL, m->signature->params [i - 1]);
+                                       m->signature->params [i - 1] = mono_metadata_type_dup (mp, m->signature->params [i - 1]);
                                        m->signature->params [i - 1]->attrs = pb->attrs;
                                }
 
@@ -8984,7 +9356,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                if (pb->cattrs) {
                                        if (!method_aux->param_cattr)
                                                method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1);
-                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs);
+                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (mp, klass->image, pb->cattrs);
                                }
                        }
                }
@@ -9000,7 +9372,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        if (specs == NULL)
                                                specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1);
                                        specs [pb->position] = 
-                                               mono_marshal_spec_from_builder (klass->image->assembly, pb->marshal_info);
+                                               mono_marshal_spec_from_builder (mp, klass->image->assembly, pb->marshal_info);
                                }
                        }
                }
@@ -9069,37 +9441,28 @@ static MonoClassField*
 fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb)
 {
        MonoClassField *field;
-       const char *p, *p2;
-       guint32 len, idx;
+       MonoType *custom;
 
        field = g_new0 (MonoClassField, 1);
 
        field->name = mono_string_to_utf8 (fb->name);
-       if (fb->attrs) {
-               /* FIXME: handle type modifiers */
-               field->type = g_memdup (fb->type->type, sizeof (MonoType));
+       if (fb->attrs || fb->modreq || fb->modopt) {
+               field->type = mono_metadata_type_dup (NULL, fb->type->type);
                field->type->attrs = fb->attrs;
+
+               g_assert (klass->image->dynamic);
+               custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt);
+               g_free (field->type);
+               field->type = custom;
        } else {
                field->type = fb->type->type;
        }
-       if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-               field->data = mono_array_addr (fb->rva_data, char, 0); /* FIXME: GC pin array */
        if (fb->offset != -1)
                field->offset = fb->offset;
        field->parent = klass;
        mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
-       if (fb->def_value) {
-               MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
-               field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-               idx = encode_constant (assembly, fb->def_value, &field->def_type);
-               /* Copy the data from the blob since it might get realloc-ed */
-               p = assembly->blob.data + idx;
-               len = mono_metadata_decode_blob_size (p, &p2);
-               len += p2 - p;
-               field->data = g_malloc (len);
-               memcpy ((gpointer)field->data, p, len);
-       }
+       // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ?
 
        return field;
 }
@@ -9178,7 +9541,9 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
+
        if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
+#ifndef DISABLE_REFLECTION_EMIT
                MonoReflectionTypeBuilder *tb;
                MonoClass *klass;
 
@@ -9187,6 +9552,10 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                klass = mono_class_from_mono_type (tb->type.type);
 
                method = methodbuilder_to_mono_method (klass, mb);
+#else
+               g_assert_not_reached ();
+               method = NULL;
+#endif
        } else {
                method = rmethod->method;
        }
@@ -9228,6 +9597,8 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 static MonoMethod *
 inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
 {
@@ -9235,7 +9606,14 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
        MonoGenericContext *context;
        int i;
 
-       g_assert (klass->generic_class);
+       /*
+        * With generic code sharing the klass might not be inflated.
+        * This can happen because classes inflated with their own
+        * type arguments are "normalized" to the uninflated class.
+        */
+       if (!klass->generic_class)
+               return method;
+
        context = mono_class_get_context (klass);
 
        if (klass->method.count) {
@@ -9251,7 +9629,7 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
                imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context);
        }
 
-       if (method->generic_container && method->klass->image->dynamic) {
+       if (method->is_generic && method->klass->image->dynamic) {
                MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
 
                mono_loader_lock ();
@@ -9286,6 +9664,7 @@ inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
        return inflate_mono_method (mono_class_from_mono_type (type->type.type), method, obj);
 }
 
+/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
 void
 mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
                                          MonoArray *ctors, MonoArray *fields, MonoArray *properties,
@@ -9322,6 +9701,8 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        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);
@@ -9337,11 +9718,10 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
 
        for (i = 0; i < dgclass->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
-               MonoClassField *field;
-               MonoInflatedField *ifield;
+               MonoClassField *field, *inflated_field = NULL;
 
                if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
-                       field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
+                       inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
                else if (!strcmp (obj->vtable->klass->name, "MonoField"))
                        field = ((MonoReflectionField *) obj)->field;
                else {
@@ -9349,16 +9729,19 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                        g_assert_not_reached ();
                }
 
-               ifield = g_new0 (MonoInflatedField, 1);
-               ifield->generic_type = field->type;
-               MOVING_GC_REGISTER (&ifield->reflection_info);
-               ifield->reflection_info = obj;
-
                dgclass->fields [i] = *field;
                dgclass->fields [i].parent = klass;
-               dgclass->fields [i].generic_info = ifield;
                dgclass->fields [i].type = mono_class_inflate_generic_type (
                        field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
+               dgclass->field_generic_types [i] = field->type;
+               MOVING_GC_REGISTER (&dgclass->field_objects [i]);
+               dgclass->field_objects [i] = obj;
+
+               if (inflated_field) {
+                       g_free (inflated_field);
+               } else {
+                       dgclass->fields [i].name = g_strdup (dgclass->fields [i].name);
+               }
        }
 
        for (i = 0; i < dgclass->count_properties; i++) {
@@ -9377,6 +9760,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                                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);
@@ -9402,6 +9786,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                                event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
                } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
                        *event = *((MonoReflectionEvent *) obj)->event;
+                       event->name = g_strdup (event->name);
 
                        if (event->add)
                                event->add = inflate_mono_method (klass, event->add, NULL);
@@ -9428,7 +9813,7 @@ ensure_runtime_vtable (MonoClass *klass)
        num = tb->ctors? mono_array_length (tb->ctors): 0;
        num += tb->num_methods;
        klass->method.count = num;
-       klass->methods = mono_mempool_alloc (klass->image->mempool, sizeof (MonoMethod*) * num);
+       klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
        num = tb->ctors? mono_array_length (tb->ctors): 0;
        for (i = 0; i < num; ++i)
                klass->methods [i] = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i));
@@ -9439,7 +9824,7 @@ ensure_runtime_vtable (MonoClass *klass)
 
        if (tb->interfaces) {
                klass->interface_count = mono_array_length (tb->interfaces);
-               klass->interfaces = mono_mempool_alloc (klass->image->mempool, sizeof (MonoClass*) * klass->interface_count);
+               klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
                for (i = 0; i < klass->interface_count; ++i) {
                        MonoReflectionType *iface = mono_array_get (tb->interfaces, gpointer, i);
                        klass->interfaces [i] = mono_class_from_mono_type (iface->type);
@@ -9524,31 +9909,40 @@ typebuilder_setup_fields (MonoClass *klass)
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionFieldBuilder *fb;
        MonoClassField *field;
+       MonoMemPool *mp = klass->image->mempool;
        const char *p, *p2;
        int i;
-       guint32 len, idx;
+       guint32 len, idx, real_size = 0;
 
        klass->field.count = tb->num_fields;
        klass->field.first = 0;
 
-       if (!klass->field.count)
+       if (tb->class_size) {
+               g_assert ((tb->packing_size & 0xfffffff0) == 0);
+               klass->packing_size = tb->packing_size;
+               real_size = klass->instance_size + tb->class_size;
+       }
+
+       if (!klass->field.count) {
+               klass->instance_size = MAX (klass->instance_size, real_size);
                return;
+       }
        
-       klass->fields = g_new0 (MonoClassField, klass->field.count);
+       klass->fields = mp_g_new0 (mp, MonoClassField, klass->field.count);
+       klass->field_def_values = mp_g_new0 (mp, MonoFieldDefaultValue, klass->field.count);
 
        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 (fb->name);
+               field->name = mp_string_to_utf8 (mp, fb->name);
                if (fb->attrs) {
-                       /* FIXME: handle type modifiers */
-                       field->type = g_memdup (fb->type->type, sizeof (MonoType));
+                       field->type = mono_metadata_type_dup (mp, fb->type->type);
                        field->type->attrs = fb->attrs;
                } else {
                        field->type = fb->type->type;
                }
                if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-                       field->data = mono_array_addr (fb->rva_data, char, 0);
+                       klass->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
                if (fb->offset != -1)
                        field->offset = fb->offset;
                field->parent = klass;
@@ -9558,15 +9952,17 @@ typebuilder_setup_fields (MonoClass *klass)
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-                       idx = encode_constant (assembly, fb->def_value, &field->def_type);
+                       idx = encode_constant (assembly, fb->def_value, &klass->field_def_values [i].def_type);
                        /* Copy the data from the blob since it might get realloc-ed */
                        p = assembly->blob.data + idx;
                        len = mono_metadata_decode_blob_size (p, &p2);
                        len += p2 - p;
-                       field->data = g_malloc (len);
-                       memcpy ((gpointer)field->data, p, len);
+                       klass->field_def_values [i].data = mono_mempool_alloc (mp, len);
+                       memcpy ((gpointer)klass->field_def_values [i].data, p, len);
                }
        }
+
+       klass->instance_size = MAX (klass->instance_size, real_size);
        mono_class_layout_fields (klass);
 }
 
@@ -9575,17 +9971,18 @@ typebuilder_setup_properties (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionPropertyBuilder *pb;
+       MonoMemPool *mp = klass->image->mempool;
        int i;
 
        klass->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
        klass->property.first = 0;
 
-       klass->properties = g_new0 (MonoProperty, klass->property.count);
+       klass->properties = mp_g_new0 (mp, MonoProperty, klass->property.count);
        for (i = 0; i < klass->property.count; ++i) {
                pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
                klass->properties [i].parent = klass;
                klass->properties [i].attrs = pb->attrs;
-               klass->properties [i].name = mono_string_to_utf8 (pb->name);
+               klass->properties [i].name = mp_string_to_utf8 (mp, pb->name);
                if (pb->get_method)
                        klass->properties [i].get = pb->get_method->mhandle;
                if (pb->set_method)
@@ -9632,17 +10029,18 @@ typebuilder_setup_events (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionEventBuilder *eb;
+       MonoMemPool *mp = klass->image->mempool;
        int i, j;
 
        klass->event.count = tb->events ? mono_array_length (tb->events) : 0;
        klass->event.first = 0;
 
-       klass->events = g_new0 (MonoEvent, klass->event.count);
+       klass->events = mp_g_new0 (mp, MonoEvent, klass->event.count);
        for (i = 0; i < klass->event.count; ++i) {
                eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
                klass->events [i].parent = klass;
                klass->events [i].attrs = eb->attrs;
-               klass->events [i].name = mono_string_to_utf8 (eb->name);
+               klass->events [i].name = mp_string_to_utf8 (mp, eb->name);
                if (eb->add_method)
                        klass->events [i].add = eb->add_method->mhandle;
                if (eb->remove_method)
@@ -9651,7 +10049,7 @@ typebuilder_setup_events (MonoClass *klass)
                        klass->events [i].raise = eb->raise_method->mhandle;
 
                if (eb->other_methods) {
-                       klass->events [i].other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1);
+                       klass->events [i].other = mp_g_new0 (mp, MonoMethod*, mono_array_length (eb->other_methods) + 1);
                        for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
                                MonoReflectionMethodBuilder *mb = 
                                        mono_array_get (eb->other_methods,
@@ -9659,6 +10057,7 @@ typebuilder_setup_events (MonoClass *klass)
                                klass->events [i].other [j] = mb->mhandle;
                        }
                }
+               mono_save_custom_attrs (klass->image, &klass->events [i], eb->cattrs);
        }
 }
 
@@ -9729,10 +10128,12 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        if (tb->subtypes) {
                for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
                        MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
-                       klass->nested_classes = g_list_prepend (klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type));
+                       klass->nested_classes = g_list_prepend_mempool (klass->image->mempool, klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type));
                }
        }
 
+       klass->nested_classes_inited = TRUE;
+
        /* fields and object layout */
        if (klass->parent) {
                if (!klass->parent->size_inited)
@@ -9792,7 +10193,9 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
 
        if (gparam->mbuilder) {
                if (!gparam->mbuilder->generic_container) {
-                       gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
+                       MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type;
+                       MonoClass *klass = my_mono_class_from_mono_type (tb->type.type);
+                       gparam->mbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
                        gparam->mbuilder->generic_container->is_method = TRUE;
                }
                param->owner = gparam->mbuilder->generic_container;
@@ -9951,6 +10354,8 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        mb->ilgen = NULL;
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 void
 mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
 {
@@ -9974,6 +10379,8 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
        return mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 /**
  * mono_reflection_lookup_dynamic_token:
  *
@@ -10083,10 +10490,12 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
 
                if (fb->handle && fb->handle->parent->generic_container) {
                        MonoClass *klass = fb->handle->parent;
-                       MonoClass *inflated = mono_class_from_mono_type (mono_class_inflate_generic_type (&klass->byval_arg, context));
+                       MonoType *type = mono_class_inflate_generic_type (&klass->byval_arg, context);
+                       MonoClass *inflated = mono_class_from_mono_type (type);
 
-                       result = mono_class_get_field_from_name (inflated, fb->handle->name);
+                       result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
                        g_assert (result);
+                       mono_metadata_free_type (type);
                }
                *handle_class = mono_defaults.fieldhandle_class;
        } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
@@ -10144,34 +10553,47 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                *handle_class = mono_defaults.methodhandle_class;
        } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
                MonoReflectionType *tb = (MonoReflectionType*)obj;
-               result = mono_class_from_mono_type (mono_class_inflate_generic_type (tb->type, context));
+               MonoType *type = mono_class_inflate_generic_type (tb->type, context);
+               result = mono_class_from_mono_type (type);
                *handle_class = mono_defaults.typehandle_class;
                g_assert (result);
+               mono_metadata_free_type (type);
        } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
                MonoReflectionGenericClass *ref = (MonoReflectionGenericClass*)obj;
-               result = mono_class_from_mono_type (mono_class_inflate_generic_type (ref->type.type, context));
+               MonoType *type = mono_class_inflate_generic_type (ref->type.type, context);
+               result = mono_class_from_mono_type (type);
                *handle_class = mono_defaults.typehandle_class;
                g_assert (result);
+               mono_metadata_free_type (type);
        } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) {
                MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj;
-               MonoClass *inflated = mono_class_from_mono_type (f->inst->type.type);
+               MonoClass *inflated;
+               MonoType *type;
+
+               type = mono_class_inflate_generic_type (f->inst->type.type, context);
+               inflated = mono_class_from_mono_type (type);
 
                g_assert (f->fb->handle);
-               result = mono_class_get_field_from_name (inflated, f->fb->handle->name);
+               result = mono_class_get_field_from_name (inflated, mono_field_get_name (f->fb->handle));
                g_assert (result);
+               mono_metadata_free_type (type);
                *handle_class = mono_defaults.fieldhandle_class;
        } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
                MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
-               MonoClass *inflated_klass = mono_class_from_mono_type (mono_class_inflate_generic_type (c->inst->type.type, context));
+               MonoType *type = mono_class_inflate_generic_type (c->inst->type.type, 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);
                *handle_class = mono_defaults.methodhandle_class;
+               mono_metadata_free_type (type);
        } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) {
                MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
-               MonoClass *inflated_klass = mono_class_from_mono_type (mono_class_inflate_generic_type (m->inst->type.type, context));
+               MonoType *type = mono_class_inflate_generic_type (m->inst->type.type, 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);
                *handle_class = mono_defaults.methodhandle_class;
+               mono_metadata_free_type (type);
        } else {
                g_print (obj->vtable->klass->name);
                g_assert_not_reached ();
@@ -10179,6 +10601,146 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
        return result;
 }
 
+#else /* DISABLE_REFLECTION_EMIT */
+
+MonoArray*
+mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
+{
+       g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported.");
+}
+
+void
+mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
+{
+       g_assert_not_reached ();
+}
+
+MonoReflectionModule *
+mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+guint32
+mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
+                                                gboolean create_methodspec, gboolean register_token)
+{
+       g_assert_not_reached ();
+       return 0;
+}
+
+void
+mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
+{
+}
+
+void
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
+                                         MonoArray *ctors, MonoArray *fields, MonoArray *properties,
+                                         MonoArray *events)
+{
+       g_assert_not_reached ();
+}
+
+void
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
+{
+       *overrides = NULL;
+       *num_overrides = 0;
+}
+
+MonoReflectionEvent *
+mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+MonoReflectionType*
+mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void
+mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
+{
+       g_assert_not_reached ();
+}
+
+MonoArray *
+mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+MonoArray *
+mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+void 
+mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+}
+
+gpointer
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
+{
+       return NULL;
+}
+
+#endif /* DISABLE_REFLECTION_EMIT */
 
 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
 const static guint32 declsec_flags_map[] = {