Do TLS using pthreads if __thread keyword not supported.
[mono.git] / mono / metadata / reflection.c
index 082a8d22bc960d7b81df6e5ad66d41e920e4ac8c..6b4774950563ea069e7672c68458dc527079a13f 100644 (file)
@@ -4,7 +4,8 @@
  * Author:
  *   Paolo Molaro (lupus@ximian.com)
  *
- * (C) 2001, 2002 Ximian, Inc.  http://www.ximian.com
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  *
  */
 #include <config.h>
 #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>
+#include <mono/metadata/security-core-clr.h>
+
+#if HAVE_SGEN_GC
+static void* reflection_info_desc = NULL;
+#define MOVING_GC_REGISTER(addr) do {  \
+               if (!reflection_info_desc) {    \
+                       gsize bmap = 1;         \
+                       reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);       \
+               }       \
+               mono_gc_register_root ((char*)(addr), sizeof (gpointer), reflection_info_desc); \
+       } while (0)
+#else
+#define MOVING_GC_REGISTER(addr)
+#endif
 
 typedef struct {
        char *p;
@@ -134,35 +148,35 @@ const unsigned char table_sizes [MONO_TABLE_NUM] = {
 
 };
 
+#ifndef DISABLE_REFLECTION_EMIT
+static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
+static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
+static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
+static void    ensure_runtime_vtable (MonoClass *klass);
+static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
+static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
+static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
+static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
+#endif
+
 static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
 static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
 static guint32 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, 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);
 static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo);
 static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
-static void    ensure_runtime_vtable (MonoClass *klass);
-static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
 static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
-static 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)
-static CRITICAL_SECTION reflection_mutex;
 
 void
 mono_reflection_init (void)
 {
-       InitializeCriticalSection (&reflection_mutex);
 }
 
 static void
@@ -215,56 +229,55 @@ sigbuffer_free (SigBuffer *buf)
        g_free (buf->buf);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /**
  * mp_g_alloc:
  *
- * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
  * from the C heap.
  */
 static gpointer
-mp_g_malloc (MonoMemPool *mp, guint size)
+image_g_malloc (MonoImage *image, guint size)
 {
-       if (mp)
-               return mono_mempool_alloc (mp, size);
+       if (image)
+               return mono_image_alloc (image, size);
        else
                return g_malloc (size);
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 /**
- * mp_g_alloc0:
+ * image_g_alloc0:
  *
- * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * Allocate memory from the @image mempool if it is non-NULL. Otherwise, allocate memory
  * from the C heap.
  */
 static gpointer
-mp_g_malloc0 (MonoMemPool *mp, guint size)
+image_g_malloc0 (MonoImage *image, guint size)
 {
-       if (mp)
-               return mono_mempool_alloc0 (mp, size);
+       if (image)
+               return mono_image_alloc0 (image, size);
        else
                return g_malloc0 (size);
 }
 
-/**
- * mp_string_to_utf8:
- *
- * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate
- * memory from the C heap.
- */
-static char *
-mp_string_to_utf8 (MonoMemPool *mp, MonoString *s)
+#ifndef DISABLE_REFLECTION_EMIT
+static char*
+image_strdup (MonoImage *image, const char *s)
 {
-       if (mp)
-               return mono_string_to_utf8_mp (mp, s);
+       if (image)
+               return mono_image_strdup (image, s);
        else
-               return mono_string_to_utf8 (s);
+               return g_strdup (s);
 }
+#endif
+
+#define image_g_new(image,struct_type, n_structs)              \
+    ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
-#define mp_g_new(mp,struct_type, n_structs)            \
-    ((struct_type *) mp_g_malloc (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+#define image_g_new0(image,struct_type, n_structs)             \
+    ((struct_type *) image_g_malloc0 (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
-#define mp_g_new0(mp,struct_type, n_structs)           \
-    ((struct_type *) mp_g_malloc0 (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
@@ -335,6 +348,7 @@ string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
        return idx;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 string_heap_init (MonoDynamicStream *sh)
 {
@@ -344,6 +358,7 @@ string_heap_init (MonoDynamicStream *sh)
        sh->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
        string_heap_insert (sh, "");
 }
+#endif
 
 static guint32
 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
@@ -384,6 +399,7 @@ stream_data_align (MonoDynamicStream *stream)
                mono_image_add_stream_data (stream, buf, 4 - count);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static int
 mono_blob_entry_hash (const char* str)
 {
@@ -412,7 +428,7 @@ mono_blob_entry_equal (const char *str1, const char *str2) {
                return 0;
        return memcmp (end1, end2, len) == 0;
 }
-
+#endif
 static guint32
 add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
 {
@@ -515,25 +531,7 @@ add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
        return idx;
 }
 
-/* modified version needed to handle building corlib */
-static MonoClass*
-my_mono_class_from_mono_type (MonoType *type) {
-       switch (type->type) {
-       case MONO_TYPE_ARRAY:
-       case MONO_TYPE_PTR:
-       case MONO_TYPE_SZARRAY:
-       case MONO_TYPE_GENERICINST:
-               return mono_class_from_mono_type (type);
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               g_assert (type->data.generic_param->pklass);
-               return type->data.generic_param->pklass;
-       default:
-               /* should be always valid when we reach this case... */
-               return type->data.klass;
-       }
-}
-
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoClass *
 default_class_from_mono_type (MonoType *type)
 {
@@ -579,6 +577,7 @@ default_class_from_mono_type (MonoType *type)
        
        return NULL;
 }
+#endif
 
 static void
 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
@@ -676,7 +675,7 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                sigbuffer_add_value (buf, type->type);
-               sigbuffer_add_value (buf, type->data.generic_param->num);
+               sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
                break;
        default:
                g_error ("need to encode type %x", type->type);
@@ -708,20 +707,21 @@ encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArra
 
        if (modreq) {
                for (i = 0; i < mono_array_length (modreq); ++i) {
-                       MonoReflectionType *mod = mono_array_get (modreq, MonoReflectionType*, i);
+                       MonoReflectionType *mod = mono_type_array_get (modreq, i);
                        sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
                        sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
                }
        }
        if (modopt) {
                for (i = 0; i < mono_array_length (modopt); ++i) {
-                       MonoReflectionType *mod = mono_array_get (modopt, MonoReflectionType*, i);
+                       MonoReflectionType *mod = mono_type_array_get (modopt, i);
                        sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
                        sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
                }
        }
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
 {
@@ -756,6 +756,7 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
        sigbuffer_free (&buf);
        return idx;
 }
+#endif
 
 static guint32
 method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
@@ -795,7 +796,7 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
                if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
                        modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
                encode_custom_modifiers (assembly, modreq, modopt, &buf);
-               pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+               pt = mono_type_array_get (mb->parameters, i);
                encode_reflection_type (assembly, pt, &buf);
        }
        if (notypes)
@@ -803,7 +804,7 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
        for (i = 0; i < notypes; ++i) {
                MonoReflectionType *pt;
 
-               pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
+               pt = mono_type_array_get (mb->opt_types, i);
                encode_reflection_type (assembly, pt, &buf);
        }
 
@@ -823,12 +824,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) {
@@ -837,13 +832,27 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
                if (lb->is_pinned)
                        sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
                
-               encode_reflection_type (assembly, lb->type, &buf);
+               encode_reflection_type (assembly, monotype_cast (lb->type), &buf);
        }
        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;
 }
 
@@ -865,8 +874,9 @@ method_count_clauses (MonoReflectionILGen *ilgen)
        return num_clauses;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoExceptionClause*
-method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
+method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
 {
        MonoExceptionClause *clauses;
        MonoExceptionClause *clause;
@@ -875,7 +885,7 @@ method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflecti
        guint32 finally_start;
        int i, j, clause_index;;
 
-       clauses = mp_g_new0 (mp, MonoExceptionClause, num_clauses);
+       clauses = image_g_new0 (image, MonoExceptionClause, num_clauses);
 
        clause_index = 0;
        for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
@@ -897,7 +907,7 @@ method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflecti
                        clause->handler_offset = ex_block->start;
                        clause->handler_len = ex_block->len;
                        if (ex_block->extype) {
-                               clause->data.catch_class = mono_class_from_mono_type (ex_block->extype->type);
+                               clause->data.catch_class = mono_class_from_mono_type (monotype_cast (ex_block->extype)->type);
                        } else {
                                if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
                                        clause->data.filter_offset = ex_block->filter_offset;
@@ -912,6 +922,7 @@ method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflecti
 
        return clauses;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 static guint32
 method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
@@ -1048,7 +1059,7 @@ fat_header:
                                        mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
                                        finally_start = ex_block->start + ex_block->len;
                                        if (ex_block->extype) {
-                                               val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, ex_block->extype->type));
+                                               val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, monotype_cast (ex_block->extype)->type));
                                        } else {
                                                if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
                                                        val = ex_block->filter_offset;
@@ -1096,9 +1107,7 @@ lookup_custom_attr (MonoImage *image, gpointer member)
 {
        MonoCustomAttrInfo* res;
 
-       mono_loader_lock ();
-       res = mono_property_hash_lookup (image->property_hash, member, MONO_PROP_DYNAMIC_CATTR);
-       mono_loader_unlock ();
+       res = mono_image_property_lookup (image, member, MONO_PROP_DYNAMIC_CATTR);
 
        if (!res)
                return NULL;
@@ -1121,7 +1130,7 @@ custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
 }
 
 static MonoCustomAttrInfo*
-mono_custom_attrs_from_builders (MonoMemPool *mp, MonoImage *image, MonoArray *cattrs)
+mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
 {
        int i, index, count, not_visible;
        MonoCustomAttrInfo *ainfo;
@@ -1143,17 +1152,16 @@ mono_custom_attrs_from_builders (MonoMemPool *mp, MonoImage *image, MonoArray *c
        }
        count -= not_visible;
 
-       ainfo = mp_g_malloc0 (mp, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
+       ainfo = image_g_malloc0 (alloc_img, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
 
        ainfo->image = image;
        ainfo->num_attrs = count;
-       ainfo->cached = mp != NULL;
+       ainfo->cached = alloc_img != 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;
@@ -1161,11 +1169,11 @@ mono_custom_attrs_from_builders (MonoMemPool *mp, MonoImage *image, MonoArray *c
                        index ++;
                }
        }
-       mono_loader_unlock ();
 
        return ainfo;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /*
  * LOCKING: Acquires the loader lock. 
  */
@@ -1177,14 +1185,17 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
        if (!cattrs || !mono_array_length (cattrs))
                return;
 
-       ainfo = mono_custom_attrs_from_builders (image->mempool, image, cattrs);
+       ainfo = mono_custom_attrs_from_builders (image, image, cattrs);
+
        mono_loader_lock ();
-       tmp = mono_property_hash_lookup (image->property_hash, obj, MONO_PROP_DYNAMIC_CATTR);
+       tmp = mono_image_property_lookup (image, 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_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
        mono_loader_unlock ();
+
 }
+#endif
 
 void
 mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
@@ -1373,7 +1384,7 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, Mono
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
 
        rmb->ilgen = mb->ilgen;
-       rmb->rtype = mb->rtype;
+       rmb->rtype = monotype_cast (mb->rtype);
        rmb->parameters = mb->parameters;
        rmb->generic_params = mb->generic_params;
        rmb->generic_container = mb->generic_container;
@@ -1439,6 +1450,7 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoRe
        rmb->refs = NULL;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
 {
@@ -1469,6 +1481,7 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, Mono
        rmb->nrefs = 0;
        rmb->refs = NULL;
 }      
+#endif
 
 static void
 mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
@@ -1577,7 +1590,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
        MonoClass *klass;
        MonoAssembly *ta;
 
-       klass = my_mono_class_from_mono_type (type);
+       klass = mono_class_from_mono_type (type);
        if (!klass) 
                return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
        ta = klass->image->assembly;
@@ -1592,11 +1605,12 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
        return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
 {
        SigBuffer buf;
-       guint32 idx;
+       guint32 idx, i;
 
        if (!assembly->save)
                return 0;
@@ -1605,11 +1619,22 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
        
        sigbuffer_add_value (&buf, 0x06);
        /* encode custom attributes before the type */
+       /* FIXME: This should probably go in encode_type () */
+       if (type->num_mods) {
+               for (i = 0; i < type->num_mods; ++i) {
+                       if (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);
        return idx;
 }
+#endif
 
 static guint32
 field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
@@ -1622,7 +1647,7 @@ field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *
        sigbuffer_add_value (&buf, 0x06);
        encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
        /* encode custom attributes before the type */
-       encode_reflection_type (assembly, fb->type, &buf);
+       encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
        return idx;
@@ -1685,7 +1710,7 @@ handle_enum:
                break;
        case MONO_TYPE_VALUETYPE:
                if (val->vtable->klass->enumtype) {
-                       *ret_type = val->vtable->klass->enum_basetype->type;
+                       *ret_type = mono_class_enum_basetype (val->vtable->klass)->type;
                        goto handle_enum;
                } else
                        g_error ("we can't encode valuetypes");
@@ -1775,7 +1800,7 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                /* custom marshaler type name */
                if (minfo->marshaltype || minfo->marshaltyperef) {
                        if (minfo->marshaltyperef)
-                               str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
+                               str = type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
                        else
                                str = mono_string_to_utf8 (minfo->marshaltype);
                        len = strlen (str);
@@ -1885,20 +1910,20 @@ property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBui
        sigbuffer_add_byte (&buf, 0x08);
        sigbuffer_add_value (&buf, nparams);
        if (mb) {
-               encode_reflection_type (assembly, mb->rtype, &buf);
+               encode_reflection_type (assembly, monotype_cast (mb->rtype), &buf);
                for (i = 0; i < nparams; ++i) {
-                       MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+                       MonoReflectionType *pt = mono_type_array_get (mb->parameters, i);
                        encode_reflection_type (assembly, pt, &buf);
                }
        } else if (smb && smb->parameters) {
                /* the property type is the last param */
-               encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf);
+               encode_reflection_type (assembly, mono_type_array_get (smb->parameters, nparams), &buf);
                for (i = 0; i < nparams; ++i) {
-                       MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
+                       MonoReflectionType *pt = mono_type_array_get (smb->parameters, i);
                        encode_reflection_type (assembly, pt, &buf);
                }
        } else {
-               encode_reflection_type (assembly, fb->type, &buf);
+               encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
        }
 
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
@@ -2060,11 +2085,9 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
 
        entry = g_new0 (GenericParamTableEntry, 1);
        entry->owner = owner;
-#ifdef HAVE_SGEN_GC
        /* FIXME: track where gen_params should be freed and remove the GC root as well */
-       MONO_GC_REGISTER_ROOT (entry->gparam);
-#endif
-       entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */
+       MOVING_GC_REGISTER (&entry->gparam);
+       entry->gparam = gparam;
 
        g_ptr_array_add (assembly->gen_params, entry);
 }
@@ -2085,8 +2108,8 @@ write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *e
 
        values [MONO_GENERICPARAM_OWNER] = entry->owner;
        values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
-       values [MONO_GENERICPARAM_NUMBER] = param->num;
-       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
+       values [MONO_GENERICPARAM_NUMBER] = mono_generic_param_num (param);
+       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, mono_generic_param_info (param)->name);
 
        mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs);
 
@@ -2229,7 +2252,7 @@ mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboo
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
        if (token)
                return token;
-       klass = my_mono_class_from_mono_type (type);
+       klass = mono_class_from_mono_type (type);
        if (!klass)
                klass = mono_class_from_mono_type (type);
 
@@ -2276,6 +2299,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        return mono_image_typedef_or_ref_full (assembly, type, TRUE);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /*
  * Insert a memberef row into the metadata: the token that point to the memberref
  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
@@ -2325,25 +2349,57 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
 }
 
 static guint32
-mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method)
+mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
 {
        guint32 token;
        MonoMethodSignature *sig;
        
+       create_typespec = create_typespec && method->is_generic && method->klass->image != &assembly->image;
+
+       if (create_typespec) {
+               token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1)));
+               if (token)
+                       return token;
+       } 
+
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
-       if (token)
+       if (token && !create_typespec)
                return token;
 
-       /*
-        * A methodref signature can't contain an unmanaged calling convention.
-        */
-       sig = mono_metadata_signature_dup (mono_method_signature (method));
-       if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
-               sig->call_convention = MONO_CALL_DEFAULT;
-       token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
-               method->name,  method_encode_signature (assembly, sig));
-       g_free (sig);
-       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+       g_assert (!method->is_inflated);
+       if (!token) {
+               /*
+                * A methodref signature can't contain an unmanaged calling convention.
+                */
+               sig = mono_metadata_signature_dup (mono_method_signature (method));
+               if ((sig->call_convention != MONO_CALL_DEFAULT) && (sig->call_convention != MONO_CALL_VARARG))
+                       sig->call_convention = MONO_CALL_DEFAULT;
+               token = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
+                       method->name,  method_encode_signature (assembly, sig));
+               g_free (sig);
+               g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+       }
+
+       if (create_typespec) {
+               MonoDynamicTable *table = &assembly->tables [MONO_TABLE_METHODSPEC];
+               g_assert (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF);
+               token = (mono_metadata_token_index (token) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
+
+               if (assembly->save) {
+                       guint32 *values;
+
+                       alloc_table (table, table->rows + 1);
+                       values = table->values + table->next_idx * MONO_METHODSPEC_SIZE;
+                       values [MONO_METHODSPEC_METHOD] = token;
+                       values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_sig (assembly, &mono_method_get_generic_container (method)->context);
+               }
+
+               token = MONO_TOKEN_METHOD_SPEC | table->next_idx;
+               table->next_idx ++;
+               /*methodspec and memberef tokens are diferent, */
+               g_hash_table_insert (assembly->handleref, GUINT_TO_POINTER (GPOINTER_TO_UINT (method) + 1), GUINT_TO_POINTER (token));
+               return token;
+       }
        return token;
 }
 
@@ -2502,20 +2558,58 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
        g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
        return token;
 }
+#endif
+
+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];
+}
 
+#ifndef DISABLE_REFLECTION_EMIT
 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;
 }
@@ -2540,7 +2634,7 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
 
        name = mono_string_to_utf8 (fb->name);
        token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, 
-                                                                                       fieldref_encode_signature (assembly, fb->type->type));
+                                                                                       field_encode_signature (assembly, fb));
        g_free (name);
        g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token));
        return token;
@@ -2785,11 +2879,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_type_array_get (modreq, 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_type_array_get (modopt, 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;
@@ -2801,7 +2940,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, monotype_cast (fb->type)->type, fb->modreq, fb->modopt);
+               sig = fieldref_encode_signature (assembly, custom);
+               g_free (custom);
+       } else {
+               sig = fieldref_encode_signature (assembly, monotype_cast (fb->type)->type);
+       }
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
        g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
@@ -2880,7 +3027,7 @@ mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigH
                        modopts = mono_array_get (helper->modopts, MonoArray*, i);
 
                encode_custom_modifiers (assembly, modreqs, modopts, &buf);
-               pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
+               pt = mono_type_array_get (helper->arguments, i);
                encode_reflection_type (assembly, pt, &buf);
        }
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
@@ -2888,7 +3035,7 @@ mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigH
 
        return idx;
 }
-       
+
 static guint32 
 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
 {
@@ -2919,6 +3066,7 @@ reflection_cc_to_file (int call_conv) {
        }
        return 0;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 typedef struct {
        MonoType *parent;
@@ -2927,6 +3075,7 @@ typedef struct {
        guint32 token;
 } ArrayMethod;
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m)
 {
@@ -2945,7 +3094,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        sig->param_count = nparams;
        sig->ret = m->ret? m->ret->type: &mono_defaults.void_class->byval_arg;
        for (i = 0; i < nparams; ++i) {
-               MonoReflectionType *t = mono_array_get (m->parameters, gpointer, i);
+               MonoReflectionType *t = mono_type_array_get (m->parameters, i);
                sig->params [i] = t->type;
        }
 
@@ -2970,6 +3119,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        m->table_idx = am->token & 0xffffff;
        return am->token;
 }
+#endif
 
 /*
  * Insert into the metadata tables all the info about the TypeBuilder tb.
@@ -2998,7 +3148,7 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
        g_free (n);
        if (tb->parent && !(is_system && is_object) && 
                        !(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
-               values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, tb->parent->type);
+               values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, monotype_cast (tb->parent)->type);
        } else {
                values [MONO_TYPEDEF_EXTENDS] = 0;
        }
@@ -3337,10 +3487,10 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        table->next_idx ++;
 
        /* Emit nested types */
-       if (klass->nested_classes) {
+       if (klass->ext && klass->ext->nested_classes) {
                GList *tmp;
 
-               for (tmp = klass->nested_classes; tmp; tmp = tmp->next)
+               for (tmp = klass->ext->nested_classes; tmp; tmp = tmp->next)
                        mono_image_fill_export_table_from_class (domain, tmp->data, module_index, table->next_idx - 1, assembly);
        }
 
@@ -3402,7 +3552,7 @@ mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder
 
        if (assemblyb->type_forwarders) {
                for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
-                       MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType*, i);
+                       MonoReflectionType *t = mono_type_array_get (assemblyb->type_forwarders, i);
                        if (!t)
                                continue;
 
@@ -3490,8 +3640,8 @@ compare_genericparam (const void *a, const void *b)
 
        if ((*b_entry)->owner == (*a_entry)->owner)
                return 
-                       (*a_entry)->gparam->type.type->data.generic_param->num - 
-                       (*b_entry)->gparam->type.type->data.generic_param->num;
+                       mono_type_get_generic_param_num ((*a_entry)->gparam->type.type) -
+                       mono_type_get_generic_param_num ((*b_entry)->gparam->type.type);
        else
                return (*a_entry)->owner - (*b_entry)->owner;
 }
@@ -3505,6 +3655,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)
 {
@@ -3567,7 +3730,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() */
@@ -3656,7 +3820,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 {
@@ -3704,6 +3868,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++){
@@ -3822,7 +3989,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")) {
@@ -4115,6 +4282,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.
@@ -4264,6 +4433,32 @@ 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 */
+
+
+typedef struct {
+       guint32 import_lookup_table;
+       guint32 timestamp;
+       guint32 forwarder;
+       guint32 name_rva;
+       guint32 import_address_table_rva;
+} MonoIDT;
+
+typedef struct {
+       guint32 name_rva;
+       guint32 flags;
+} MonoILT;
+
+#ifndef DISABLE_REFLECTION_EMIT
+
 /*
  * mono_image_insert_string:
  * @module: module builder object
@@ -4402,6 +4597,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
        guint32 token = 0;
 
        klass = obj->vtable->klass;
+
+       /* Check for user defined reflection objects */
+       /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
+       if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0))
+               mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported")); \
+
        if (strcmp (klass->name, "MethodBuilder") == 0) {
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
@@ -4473,12 +4674,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                                token = MONO_TOKEN_METHOD_DEF | method_table_idx;
                        }
                } else {
-                       token = mono_image_get_methodref_token (assembly, m->method);
+                       token = mono_image_get_methodref_token (assembly, m->method, create_methodspec);
                }
                /*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;
@@ -4533,21 +4734,6 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject
        }
 }
 
-typedef struct {
-       guint32 import_lookup_table;
-       guint32 timestamp;
-       guint32 forwarder;
-       guint32 name_rva;
-       guint32 import_address_table_rva;
-} MonoIDT;
-
-typedef struct {
-       guint32 name_rva;
-       guint32 flags;
-} MonoILT;
-
-static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
-
 static MonoDynamicImage*
 create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
 {
@@ -4585,14 +4771,14 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
 
        mono_image_init (&image->image);
 
-       image->token_fixups = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
+       image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
        image->method_to_table_idx = g_hash_table_new (NULL, NULL);
        image->field_to_table_idx = g_hash_table_new (NULL, NULL);
        image->method_aux_hash = g_hash_table_new (NULL, NULL);
        image->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->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, 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);
@@ -4629,6 +4815,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
 
        return image;
 }
+#endif
 
 static void
 free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
@@ -4659,6 +4846,8 @@ 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);
@@ -4671,9 +4860,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                        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 ((char*)mono_generic_param_info (param)->name);
                                g_free (param);
-                               g_free (entry->gparam->type.type);
                        }
                        g_free (entry);
                }
@@ -4705,6 +4893,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
        }
 }      
 
+#ifndef DISABLE_REFLECTION_EMIT
+
 /*
  * mono_image_basic_init:
  * @assembly: an assembly builder object
@@ -4779,6 +4969,10 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
        mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
 }
 
+#endif /* !DISABLE_REFLECTION_EMIT */
+
+#ifndef DISABLE_REFLECTION_EMIT_SAVE
+
 static int
 calc_section_size (MonoDynamicImage *assembly)
 {
@@ -5063,7 +5257,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;
@@ -5281,7 +5476,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);
@@ -5415,6 +5610,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)
 {
@@ -5470,6 +5677,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.
@@ -5511,10 +5720,15 @@ reflected_hash (gconstpointer a) {
         mono_domain_unlock (domain); \
        } while (0)
 
-#ifndef HAVE_NULL_GC
-#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL)
+#ifdef HAVE_BOEHM_GC
+/* ReflectedEntry doesn't need to be GC tracked */
+#define ALLOC_REFENTRY g_new0 (ReflectedEntry, 1)
+#define FREE_REFENTRY(entry) g_free ((entry))
+#define REFENTRY_REQUIRES_CLEANUP
 #else
 #define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
+/* FIXME: */
+#define FREE_REFENTRY(entry)
 #endif
 
 #define CACHE_OBJECT(t,p,o,k)  \
@@ -5538,6 +5752,46 @@ reflected_hash (gconstpointer a) {
         return _obj; \
        } while (0)
 
+static void
+clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
+{
+       mono_domain_lock (domain);
+       if (domain->refobject_hash) {
+        ReflectedEntry pe;
+               gpointer orig_pe, orig_value;
+
+               pe.item = o;
+               pe.refclass = klass;
+               if (mono_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
+                       mono_g_hash_table_remove (domain->refobject_hash, &pe);
+                       FREE_REFENTRY (orig_pe);
+               }
+       }
+       mono_domain_unlock (domain);
+}
+
+#ifdef REFENTRY_REQUIRES_CLEANUP
+static void
+cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
+{
+       FREE_REFENTRY (key);
+}
+#endif
+
+void
+mono_reflection_cleanup_domain (MonoDomain *domain)
+{
+       if (domain->refobject_hash) {
+/*let's avoid scanning the whole hashtable if not needed*/
+#ifdef REFENTRY_REQUIRES_CLEANUP
+               mono_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
+#endif
+               mono_g_hash_table_destroy (domain->refobject_hash);
+               domain->refobject_hash = NULL;
+       }
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
 static gpointer
 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
 {
@@ -5587,6 +5841,8 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
        }
 }
 
+#endif
+
 /*
  * mono_assembly_get_object:
  * @domain: an app domain
@@ -5808,7 +6064,6 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
        mono_class_init (klass);
 
 #ifdef HAVE_SGEN_GC
-       /* FIXME: allow unpinned later */
        res = (MonoReflectionGenericClass *) mono_gc_alloc_pinned_obj (mono_class_vtable (domain, System_Reflection_MonoGenericClass), mono_class_instance_size (System_Reflection_MonoGenericClass));
 #else
        res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
@@ -5871,6 +6126,10 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
         */
        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.
@@ -5884,12 +6143,14 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                        return vtable->type;
        }
 
+       mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
        mono_domain_lock (domain);
        if (!domain->type_hash)
                domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
                                (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
        if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
                mono_domain_unlock (domain);
+               mono_loader_unlock ();
                return res;
        }
        /* Create a MonoGenericClass object for instantiations of not finished TypeBuilders */
@@ -5897,11 +6158,13 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
                mono_g_hash_table_insert (domain->type_hash, type, res);
                mono_domain_unlock (domain);
+               mono_loader_unlock ();
                return res;
        }
 
        if (!verify_safe_for_managed_space (type)) {
                mono_domain_unlock (domain);
+               mono_loader_unlock ();
                mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space"));
        }
 
@@ -5910,6 +6173,7 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                /* should this be considered an error condition? */
                if (!type->byref) {
                        mono_domain_unlock (domain);
+                       mono_loader_unlock ();
                        return klass->reflection_info;
                }
        }
@@ -5922,7 +6186,12 @@ 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);
+       mono_loader_unlock ();
        return res;
 }
 
@@ -5996,6 +6265,21 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
        CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
 }
 
+/*
+ * mono_method_clear_object:
+ *
+ *   Clear the cached reflection objects for the dynamic method METHOD.
+ */
+void
+mono_method_clear_object (MonoDomain *domain, MonoMethod *method)
+{
+       g_assert (method->dynamic);
+
+       clear_cached_object (domain, method, method->klass);
+       /* Added by mono_param_get_objects () */
+       clear_cached_object (domain, &(method->signature), NULL);
+}
+
 /*
  * mono_field_get_object:
  * @domain: an app domain
@@ -6017,9 +6301,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));
@@ -6063,14 +6347,16 @@ MonoReflectionEvent*
 mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
 {
        MonoReflectionEvent *res;
+       MonoReflectionMonoEvent *mono_event;
        static MonoClass *monoevent_klass;
 
        CHECK_OBJECT (MonoReflectionEvent *, event, klass);
        if (!monoevent_klass)
                monoevent_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
-       res = (MonoReflectionEvent *)mono_object_new (domain, monoevent_klass);
-       res->klass = klass;
-       res->event = event;
+       mono_event = (MonoReflectionMonoEvent *)mono_object_new (domain, monoevent_klass);
+       mono_event->klass = klass;
+       mono_event->event = event;
+       res = (MonoReflectionEvent*)mono_event;
        CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
 }
 
@@ -6127,7 +6413,7 @@ get_reflection_missing (MonoDomain *domain, MonoObject **reflection_missing)
  * in the method @method.
  */
 MonoArray*
-mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
+mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass)
 {
        static MonoClass *System_Reflection_ParameterInfo;
        static MonoClass *System_Reflection_ParameterInfo_array;
@@ -6162,10 +6448,10 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        /* Note: the cache is based on the address of the signature into the method
         * since we already cache MethodInfos with the method as keys.
         */
-       CHECK_OBJECT (MonoArray*, &(method->signature), NULL);
+       CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
 
        sig = mono_method_signature (method);
-       member = mono_method_get_object (domain, method, NULL);
+       member = mono_method_get_object (domain, method, refclass);
        names = g_new (char *, sig->param_count);
        mono_method_get_param_names (method, (const char **) names);
 
@@ -6237,7 +6523,13 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
                        mono_metadata_free_marshal_spec (mspecs [i]);
        g_free (mspecs);
        
-       CACHE_OBJECT (MonoArray *, &(method->signature), res, NULL);
+       CACHE_OBJECT (MonoArray *, &(method->signature), res, refclass);
+}
+
+MonoArray*
+mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
+{
+       return mono_param_get_objects_internal (domain, method, NULL);
 }
 
 /*
@@ -6303,11 +6595,11 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        ret->init_locals = header->init_locals;
        ret->max_stack = header->max_stack;
        ret->local_var_sig_token = local_var_sig_token;
-       MONO_OBJECT_SETREF (ret, il, mono_array_new (domain, mono_defaults.byte_class, header->code_size));
+       MONO_OBJECT_SETREF (ret, il, mono_array_new_cached (domain, mono_defaults.byte_class, header->code_size));
        memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
 
        /* Locals */
-       MONO_OBJECT_SETREF (ret, locals, mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals));
+       MONO_OBJECT_SETREF (ret, locals, mono_array_new_cached (domain, System_Reflection_LocalVariableInfo, header->num_locals));
        for (i = 0; i < header->num_locals; ++i) {
                MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo);
                MONO_OBJECT_SETREF (info, local_type, mono_type_get_object (domain, header->locals [i]));
@@ -6317,7 +6609,7 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        }
 
        /* Exceptions */
-       MONO_OBJECT_SETREF (ret, clauses, mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses));
+       MONO_OBJECT_SETREF (ret, clauses, mono_array_new_cached (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses));
        for (i = 0; i < header->num_clauses; ++i) {
                MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new (domain, System_Reflection_ExceptionHandlingClause);
                MonoExceptionClause *clause = &header->clauses [i];
@@ -6448,7 +6740,7 @@ mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
                object = mono_object_new (domain, klass);
                retval = ((gchar *) object + sizeof (MonoObject));
                if (klass->enumtype)
-                       basetype = klass->enum_basetype;
+                       basetype = mono_class_enum_basetype (klass);
        } else {
                retval = &object;
        }
@@ -6575,6 +6867,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
 
        /* last_point separates the namespace from the name */
        last_point = NULL;
+       /* Skips spaces */
+       while (*p == ' ') p++, start++, w++, name++;
 
        while (*p) {
                switch (*p) {
@@ -7076,16 +7370,22 @@ 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;
 
                token = mono_class_get_property_token (p->property);
        } else if (strcmp (klass->name, "MonoEvent") == 0) {
-               MonoReflectionEvent *p = (MonoReflectionEvent*)obj;
+               MonoReflectionMonoEvent *p = (MonoReflectionMonoEvent*)obj;
 
                token = mono_class_get_event_token (p->event);
        } else if (strcmp (klass->name, "ParameterInfo") == 0) {
@@ -7163,7 +7463,7 @@ handle_enum:
        }
        case MONO_TYPE_VALUETYPE:
                if (t->data.klass->enumtype) {
-                       type = t->data.klass->enum_basetype->type;
+                       type = mono_class_enum_basetype (t->data.klass)->type;
                        goto handle_enum;
                } else {
                        g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
@@ -7258,7 +7558,7 @@ handle_type:
                arr = mono_array_new (mono_domain_get(), tklass, alen);
                basetype = tklass->byval_arg.type;
                if (basetype == MONO_TYPE_VALUETYPE && tklass->enumtype)
-                       basetype = tklass->enum_basetype->type;
+                       basetype = mono_class_enum_basetype (tklass)->type;
                switch (basetype)
                {
                        case MONO_TYPE_U1:
@@ -7422,9 +7722,9 @@ static guint32
 find_property_index (MonoClass *klass, MonoProperty *property) {
        int i;
 
-       for (i = 0; i < klass->property.count; ++i) {
-               if (property == &klass->properties [i])
-                       return klass->property.first + 1 + i;
+       for (i = 0; i < klass->ext->property.count; ++i) {
+               if (property == &klass->ext->properties [i])
+                       return klass->ext->property.first + 1 + i;
        }
        return 0;
 }
@@ -7436,9 +7736,9 @@ static guint32
 find_event_index (MonoClass *klass, MonoEvent *event) {
        int i;
 
-       for (i = 0; i < klass->event.count; ++i) {
-               if (event == &klass->events [i])
-                       return klass->event.first + 1 + i;
+       for (i = 0; i < klass->ext->event.count; ++i) {
+               if (event == &klass->ext->events [i])
+                       return klass->ext->event.first + 1 + i;
        }
        return 0;
 }
@@ -7450,7 +7750,9 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
        const char *named;
        guint32 i, j, num_named;
        MonoObject *attr;
+       void *params_buf [32];
        void **params;
+       MonoMethodSignature *sig;
 
        mono_class_init (method->klass);
 
@@ -7465,8 +7767,12 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
 
        /*g_print ("got attr %s\n", method->klass->name);*/
 
-       /* Allocate using alloca so it gets GC tracking */
-       params = alloca (mono_method_signature (method)->param_count * sizeof (void*)); 
+       sig = mono_method_signature (method);
+       if (sig->param_count < 32)
+               params = params_buf;
+       else
+               /* Allocate using GC so it gets GC tracking */
+               params = mono_gc_alloc_fixed (sig->param_count * sizeof (void*), NULL);
 
        /* skip prolog */
        p += 2;
@@ -7526,6 +7832,9 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
                g_free (name);
        }
 
+       if (params != params_buf)
+               mono_gc_free_fixed (params);
+
        return attr;
 }
 
@@ -7652,7 +7961,7 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
        MonoObject *attr;
        int i;
 
-       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
+       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
                if (!cinfo->attrs [i].ctor)
                        /* The cattr type is not finished yet */
@@ -7677,7 +7986,7 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
                        n ++;
        }
 
-       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, n);
+       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n);
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
                if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
@@ -7784,6 +8093,10 @@ mono_custom_attrs_from_method (MonoMethod *method)
        if (method->dynamic || method->klass->image->dynamic)
                return lookup_custom_attr (method->klass->image, method);
 
+       if (!method->token)
+               /* Synthetic methods */
+               return NULL;
+
        idx = mono_method_get_index (method);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_METHODDEF;
@@ -7952,7 +8265,7 @@ mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
        MonoClass *klass;
        for (i = 0; i < ainfo->num_attrs; ++i) {
                klass = ainfo->attrs [i].ctor->klass;
-               if (mono_class_has_parent (klass, attr_klass))
+               if (mono_class_has_parent (klass, attr_klass) || (MONO_CLASS_IS_INTERFACE (attr_klass) && mono_class_is_assignable_from (attr_klass, klass)))
                        return TRUE;
        }
        return FALSE;
@@ -7989,6 +8302,8 @@ mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
  *
  * Return the custom attribute info for attributes defined for the
  * reflection handle @obj. The objects.
+ *
+ * FIXME this function leaks like a sieve for SRE objects.
  */
 MonoCustomAttrInfo*
 mono_reflection_get_custom_attrs_info (MonoObject *obj)
@@ -8011,7 +8326,7 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
                cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
        } else if (strcmp ("MonoEvent", klass->name) == 0) {
-               MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
+               MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
                cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
        } else if (strcmp ("MonoField", klass->name) == 0) {
                MonoReflectionField *rfield = (MonoReflectionField*)obj;
@@ -8080,7 +8395,7 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
        } else {
                if (mono_loader_get_last_error ())
                        return NULL;
-               result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, 0);
+               result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0);
        }
 
        return result;
@@ -8137,6 +8452,7 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
         return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* t)
 {
@@ -8154,17 +8470,17 @@ mono_reflection_type_get_handle (MonoReflectionType* t)
  * LOCKING: Assumes the loader lock is held.
  */
 static MonoMethodSignature*
-parameters_to_signature (MonoMemPool *mp, MonoArray *parameters) {
+parameters_to_signature (MonoImage *image, MonoArray *parameters) {
        MonoMethodSignature *sig;
        int count, i;
 
        count = parameters? mono_array_length (parameters): 0;
 
-       sig = mp_g_malloc0 (mp, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+       sig = image_g_malloc0 (image, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
        sig->param_count = count;
        sig->sentinelpos = -1; /* FIXME */
        for (i = 0; i < count; ++i) {
-               MonoReflectionType *pt = mono_array_get (parameters, MonoReflectionType*, i);
+               MonoReflectionType *pt = mono_type_array_get (parameters, i);
                sig->params [i] = mono_reflection_type_get_handle (pt);
        }
        return sig;
@@ -8174,10 +8490,10 @@ parameters_to_signature (MonoMemPool *mp, MonoArray *parameters) {
  * LOCKING: Assumes the loader lock is held.
  */
 static MonoMethodSignature*
-ctor_builder_to_signature (MonoMemPool *mp, MonoReflectionCtorBuilder *ctor) {
+ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilder *ctor) {
        MonoMethodSignature *sig;
 
-       sig = parameters_to_signature (mp, ctor->parameters);
+       sig = parameters_to_signature (image, ctor->parameters);
        sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
        sig->ret = &mono_defaults.void_class->byval_arg;
        return sig;
@@ -8187,12 +8503,12 @@ ctor_builder_to_signature (MonoMemPool *mp, MonoReflectionCtorBuilder *ctor) {
  * LOCKING: Assumes the loader lock is held.
  */
 static MonoMethodSignature*
-method_builder_to_signature (MonoMemPool *mp, MonoReflectionMethodBuilder *method) {
+method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilder *method) {
        MonoMethodSignature *sig;
 
-       sig = parameters_to_signature (mp, method->parameters);
+       sig = parameters_to_signature (image, method->parameters);
        sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
-       sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
+       sig->ret = method->rtype? monotype_cast (method->rtype)->type: &mono_defaults.void_class->byval_arg;
        sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
        return sig;
 }
@@ -8215,7 +8531,7 @@ get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type)
        if (strcmp (klass->name, "PropertyBuilder") == 0) {
                MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
                *name = mono_string_to_utf8 (pb->name);
-               *type = pb->type->type;
+               *type = monotype_cast (pb->type)->type;
        } else {
                MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
                *name = g_strdup (p->property->name);
@@ -8233,13 +8549,14 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
        if (strcmp (klass->name, "FieldBuilder") == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
                *name = mono_string_to_utf8 (fb->name);
-               *type = fb->type->type;
+               *type = monotype_cast (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;
        }
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 /*
  * Encode a value in a custom attribute stream of bytes.
@@ -8309,7 +8626,7 @@ handle_enum:
                break;
        case MONO_TYPE_VALUETYPE:
                if (type->data.klass->enumtype) {
-                       simple_type = type->data.klass->enum_basetype->type;
+                       simple_type = mono_class_enum_basetype (type->data.klass)->type;
                        goto handle_enum;
                } else {
                        g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
@@ -8477,7 +8794,7 @@ handle_type:
                memcpy (p, str, slen);
                p += slen;
                g_free (str);
-               simple_type = klass->enum_basetype->type;
+               simple_type = mono_class_enum_basetype (klass)->type;
                goto handle_enum;
        }
        default:
@@ -8518,6 +8835,7 @@ encode_field_or_prop_type (MonoType *type, char *p, char **retp)
        *retp = p;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
 {
@@ -8643,19 +8961,6 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
        return result;
 }
 
-#if HAVE_SGEN_GC
-static void* reflection_info_desc = NULL;
-#define MOVING_GC_REGISTER(addr) do {  \
-               if (!reflection_info_desc) {    \
-                       gsize bmap = 1;         \
-                       reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);       \
-               }       \
-               mono_gc_register_root ((addr), sizeof (gpointer), reflection_info_desc);        \
-       } while (0)
-#else
-#define MOVING_GC_REGISTER(addr)
-#endif
-
 /*
  * mono_reflection_setup_internal_class:
  * @tb: a TypeBuilder object
@@ -8671,15 +8976,17 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
+       CHECK_MONOTYPE (tb->parent);
+
        mono_loader_lock ();
 
        if (tb->parent) {
                /* check so we can compile corlib correctly */
                if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
                        /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
-                       parent = tb->parent->type->data.klass;
+                       parent = monotype_cast (tb->parent)->type->data.klass;
                } else {
-                       parent = my_mono_class_from_mono_type (tb->parent->type);
+                       parent = mono_class_from_mono_type (monotype_cast (tb->parent)->type);
                }
        } else {
                parent = NULL;
@@ -8697,13 +9004,13 @@ 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;
 
        klass->inited = 1; /* we lie to the runtime */
-       klass->name = mono_string_to_utf8_mp (klass->image->mempool, tb->name);
-       klass->name_space = mono_string_to_utf8_mp (klass->image->mempool, tb->nspace);
+       klass->name = mono_string_to_utf8_image (klass->image, tb->name);
+       klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace);
        klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
        klass->flags = tb->attrs;
        
@@ -8769,16 +9076,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 void
 mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
 {
-       MonoClass *klass;
-
-       MONO_ARCH_SAVE_REGS;
-
-       klass = my_mono_class_from_mono_type (tb->type.type);
-       if (tb->generic_container)
-               return;
-
-       tb->generic_container = mono_mempool_alloc0 (klass->image->mempool, sizeof (MonoGenericContainer));
-       tb->generic_container->owner.klass = klass;
 }
 
 /*
@@ -8795,7 +9092,7 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
 
@@ -8804,20 +9101,23 @@ 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 (MonoGenericParamFull) * count);
+
+       klass->is_generic = 1;
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
-               klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param;
+               MonoGenericParamFull *param = (MonoGenericParamFull *) gparam->type.type->data.generic_param;
+               klass->generic_container->type_params [i] = *param;
                /*Make sure we are a diferent type instance */
-               klass->generic_container->type_params [i].owner = klass->generic_container;
-               klass->generic_container->type_params [i].pklass = NULL;
+               klass->generic_container->type_params [i].param.owner = klass->generic_container;
+               klass->generic_container->type_params [i].info.pklass = NULL;
 
-               g_assert (klass->generic_container->type_params [i].owner);
+               g_assert (klass->generic_container->type_params [i].param.owner);
        }
 
        klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
@@ -8836,32 +9136,33 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        mono_loader_lock ();
-       if (klass->enumtype && klass->enum_basetype == NULL) {
+       if (klass->enumtype && mono_class_enum_basetype (klass) == NULL) {
                MonoReflectionFieldBuilder *fb;
                MonoClass *ec;
+               MonoType *enum_basetype;
 
                g_assert (tb->fields != NULL);
                g_assert (mono_array_length (tb->fields) >= 1);
 
                fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
 
-               if (!mono_type_is_valid_enum_basetype (fb->type->type)) {
+               if (!mono_type_is_valid_enum_basetype (monotype_cast (fb->type)->type)) {
                        mono_loader_unlock ();
                        return;
                }
 
-               klass->enum_basetype = fb->type->type;
-               klass->element_class = my_mono_class_from_mono_type (klass->enum_basetype);
+               enum_basetype = monotype_cast (fb->type)->type;
+               klass->element_class = mono_class_from_mono_type (enum_basetype);
                if (!klass->element_class)
-                       klass->element_class = mono_class_from_mono_type (klass->enum_basetype);
+                       klass->element_class = mono_class_from_mono_type (enum_basetype);
 
                /*
                 * get the element_class from the current corlib.
                 */
-               ec = default_class_from_mono_type (klass->enum_basetype);
+               ec = default_class_from_mono_type (enum_basetype);
                klass->instance_size = ec->instance_size;
                klass->size_inited = 1;
                /* 
@@ -8875,12 +9176,12 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
 }
 
 static MonoMarshalSpec*
-mono_marshal_spec_from_builder (MonoMemPool *mp, MonoAssembly *assembly,
+mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
                                                                MonoReflectionMarshal *minfo)
 {
        MonoMarshalSpec *res;
 
-       res = mp_g_new0 (mp, MonoMarshalSpec, 1);
+       res = image_g_new0 (image, MonoMarshalSpec, 1);
        res->native = minfo->type;
 
        switch (minfo->type) {
@@ -8906,7 +9207,7 @@ mono_marshal_spec_from_builder (MonoMemPool *mp, MonoAssembly *assembly,
        case MONO_NATIVE_CUSTOM:
                if (minfo->marshaltyperef)
                        res->data.custom_data.custom_name =
-                               type_get_fully_qualified_name (minfo->marshaltyperef->type);
+                               type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
                if (minfo->mcookie)
                        res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
                break;
@@ -8917,6 +9218,7 @@ mono_marshal_spec_from_builder (MonoMemPool *mp, MonoAssembly *assembly,
 
        return res;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 MonoReflectionMarshal*
 mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
@@ -8966,6 +9268,7 @@ mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
        return minfo;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoMethod*
 reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                         ReflectionMethodBuilder *rmb,
@@ -8975,7 +9278,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        MonoMethodNormal *pm;
        MonoMarshalSpec **specs;
        MonoReflectionMethodAux *method_aux;
-       MonoMemPool *mp;
+       MonoImage *image;
        gboolean dynamic;
        int i;
 
@@ -8985,7 +9288,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
         * malloc'd.
         */
        dynamic = rmb->refs != NULL;
-       mp = dynamic ? NULL : klass->image->mempool;
+       image = dynamic ? NULL : klass->image;
 
        if (!dynamic)
                g_assert (!klass->generic_class);
@@ -8994,11 +9297,11 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
        if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
-               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodPInvoke, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
        else if (rmb->refs)
-               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodWrapper, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
        else
-               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodNormal, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodNormal, 1);
 
        pm = (MonoMethodNormal*)m;
 
@@ -9006,7 +9309,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        m->slot = -1;
        m->flags = rmb->attrs;
        m->iflags = rmb->iattrs;
-       m->name = mp_string_to_utf8 (mp, rmb->name);
+       m->name = mono_string_to_utf8_image (image, rmb->name);
        m->klass = klass;
        m->signature = sig;
        m->skip_visibility = rmb->skip_visibility;
@@ -9021,10 +9324,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
                m->signature->pinvoke = 1;
 
-               method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
+               method_aux = image_g_new0 (image, 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);
+               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry) : image_strdup (image, m->name);
+               method_aux->dll = mono_string_to_utf8_image (image, rmb->dll);
                
                ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
 
@@ -9064,10 +9367,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        }
                }
 
-               header = mp_g_malloc0 (mp, sizeof (MonoMethodHeader) + 
+               header = image_g_malloc0 (image, sizeof (MonoMethodHeader) + 
                        (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
                header->code_size = code_size;
-               header->code = mp_g_malloc (mp, code_size);
+               header->code = image_g_malloc (image, code_size);
                memcpy ((char*)header->code, code, code_size);
                header->max_stack = max_stack;
                header->init_locals = rmb->init_locals;
@@ -9077,13 +9380,13 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        MonoReflectionLocalBuilder *lb = 
                                mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
 
-                       header->locals [i] = mp_g_new0 (mp, MonoType, 1);
-                       memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
+                       header->locals [i] = image_g_new0 (image, MonoType, 1);
+                       memcpy (header->locals [i], monotype_cast (lb->type)->type, sizeof (MonoType));
                }
 
                header->num_clauses = num_clauses;
                if (num_clauses) {
-                       header->clauses = method_encode_clauses (mp, (MonoDynamicImage*)klass->image,
+                       header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
                                 rmb->ilgen, num_clauses);
                }
 
@@ -9100,14 +9403,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        mono_method_set_generic_container (m, container);
                }
                container->type_argc = count;
-               container->type_params = mp_g_new0 (mp, MonoGenericParam, count);
+               container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
                container->owner.method = m;
 
                for (i = 0; i < count; i++) {
                        MonoReflectionGenericParam *gp =
                                mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
-
-                       container->type_params [i] = *gp->type.type->data.generic_param;
+                       MonoGenericParamFull *param = (MonoGenericParamFull *) gp->type.type->data.generic_param;
+                       container->type_params [i] = *param;
                }
 
                if (klass->generic_container) {
@@ -9124,7 +9427,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
                m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
 
-               mw->method_data = data = mp_g_new (mp, gpointer, rmb->nrefs + 1);
+               mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
                data [0] = GUINT_TO_POINTER (rmb->nrefs);
                for (i = 0; i < rmb->nrefs; ++i)
                        data [i + 1] = rmb->refs [i];
@@ -9135,14 +9438,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        /* Parameter info */
        if (rmb->pinfo) {
                if (!method_aux)
-                       method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
-               method_aux->param_names = mp_g_new0 (mp, char *, mono_method_signature (m)->param_count + 1);
+                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
+               method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
                for (i = 0; i <= m->signature->param_count; ++i) {
                        MonoReflectionParamBuilder *pb;
                        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 */
-                                       m->signature->params [i - 1] = mono_metadata_type_dup (mp, m->signature->params [i - 1]);
+                                       m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
                                        m->signature->params [i - 1]->attrs = pb->attrs;
                                }
 
@@ -9153,8 +9456,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        const char *p2;
 
                                        if (!method_aux->param_defaults) {
-                                               method_aux->param_defaults = mp_g_new0 (mp, guint8*, m->signature->param_count + 1);
-                                               method_aux->param_default_types = mp_g_new0 (mp, guint32, m->signature->param_count + 1);
+                                               method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
+                                               method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
                                        }
                                        assembly = (MonoDynamicImage*)klass->image;
                                        idx = encode_constant (assembly, pb->def_value, &def_type);
@@ -9162,17 +9465,17 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        p = assembly->blob.data + idx;
                                        len = mono_metadata_decode_blob_size (p, &p2);
                                        len += p2 - p;
-                                       method_aux->param_defaults [i] = mp_g_malloc (mp, len);
+                                       method_aux->param_defaults [i] = image_g_malloc (image, len);
                                        method_aux->param_default_types [i] = def_type;
                                        memcpy ((gpointer)method_aux->param_defaults [i], p, len);
                                }
 
                                if (pb->name)
-                                       method_aux->param_names [i] = mp_string_to_utf8 (mp, pb->name);
+                                       method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name);
                                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 (mp, klass->image, pb->cattrs);
+                                               method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
+                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
                                }
                        }
                }
@@ -9186,15 +9489,15 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
                                if (pb->marshal_info) {
                                        if (specs == NULL)
-                                               specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1);
+                                               specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
                                        specs [pb->position] = 
-                                               mono_marshal_spec_from_builder (mp, klass->image->assembly, pb->marshal_info);
+                                               mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info);
                                }
                        }
                }
        if (specs != NULL) {
                if (!method_aux)
-                       method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
+                       method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
                method_aux->param_marshall = specs;
        }
 
@@ -9213,7 +9516,7 @@ ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb)
        MonoMethodSignature *sig;
 
        mono_loader_lock ();
-       sig = ctor_builder_to_signature (klass->image->mempool, mb);
+       sig = ctor_builder_to_signature (klass->image, mb);
        mono_loader_unlock ();
 
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
@@ -9237,7 +9540,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb)
        MonoMethodSignature *sig;
 
        mono_loader_lock ();
-       sig = method_builder_to_signature (klass->image->mempool, mb);
+       sig = method_builder_to_signature (klass->image, mb);
        mono_loader_unlock ();
 
        reflection_methodbuilder_from_method_builder (&rmb, mb);
@@ -9257,39 +9560,32 @@ 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) {
-               field->type = mono_metadata_type_dup (NULL, fb->type->type);
+       if (fb->attrs || fb->modreq || fb->modopt) {
+               field->type = mono_metadata_type_dup (NULL, monotype_cast (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;
+               field->type = monotype_cast (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;
 }
+#endif
 
 MonoType*
 mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
@@ -9358,14 +9654,16 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        MonoClass *klass;
        MonoMethod *method, *inflated;
        MonoMethodInflated *imethod;
-       MonoReflectionMethodBuilder *mb = NULL;
        MonoGenericContext tmp_context;
        MonoGenericInst *ginst;
        MonoType **type_argv;
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
+
        if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
+#ifndef DISABLE_REFLECTION_EMIT
+               MonoReflectionMethodBuilder *mb = NULL;
                MonoReflectionTypeBuilder *tb;
                MonoClass *klass;
 
@@ -9374,6 +9672,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;
        }
@@ -9415,6 +9717,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)
 {
@@ -9422,7 +9726,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) {
@@ -9510,6 +9821,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);
@@ -9526,7 +9839,6 @@ 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, *inflated_field = NULL;
-               MonoInflatedField *ifield;
 
                if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
                        inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
@@ -9537,19 +9849,15 @@ 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 ((char*)inflated_field->data);
                        g_free (inflated_field);
                } else {
                        dgclass->fields [i].name = g_strdup (dgclass->fields [i].name);
@@ -9597,7 +9905,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                        if (eb->remove_method)
                                event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
                } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
-                       *event = *((MonoReflectionEvent *) obj)->event;
+                       *event = *((MonoReflectionMonoEvent *) obj)->event;
                        event->name = g_strdup (event->name);
 
                        if (event->add)
@@ -9611,36 +9919,78 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        dgclass->initialized = TRUE;
 }
 
+static void
+ensure_generic_class_runtime_vtable (MonoClass *klass)
+{
+       MonoClass *gklass = klass->generic_class->container_class;
+       int i;
+
+       if (klass->wastypebuilder)
+               return;
+
+       ensure_runtime_vtable (gklass);
+
+       klass->method.count = gklass->method.count;
+       klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));
+
+       for (i = 0; i < klass->method.count; i++) {
+               klass->methods [i] = mono_class_inflate_generic_method_full (
+                       gklass->methods [i], klass, mono_class_get_context (klass));
+       }
+
+       klass->interface_count = gklass->interface_count;
+       klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
+       for (i = 0; i < klass->interface_count; ++i) {
+               MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
+               klass->interfaces [i] = mono_class_from_mono_type (iface_type);
+               mono_metadata_free_type (iface_type);
+
+               ensure_runtime_vtable (klass->interfaces [i]);
+       }
+       klass->interfaces_inited = 1;
+
+       /*We can only finish with this klass once it's parent has as well*/
+       if (gklass->wastypebuilder)
+               klass->wastypebuilder = TRUE;
+       return;
+}
+
 static void
 ensure_runtime_vtable (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        int i, num, j;
 
-       if (!tb || klass->wastypebuilder)
+       if (!klass->image->dynamic || (!tb && !klass->generic_class) || klass->wastypebuilder)
                return;
        if (klass->parent)
                ensure_runtime_vtable (klass->parent);
 
-       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);
-       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));
-       num = tb->num_methods;
-       j = i;
-       for (i = 0; i < num; ++i)
-               klass->methods [j++] = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i));
-
-       if (tb->interfaces) {
-               klass->interface_count = mono_array_length (tb->interfaces);
-               klass->interfaces = mono_mempool_alloc (klass->image->mempool, 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);
+       if (tb) {
+               num = tb->ctors? mono_array_length (tb->ctors): 0;
+               num += tb->num_methods;
+               klass->method.count = 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));
+               num = tb->num_methods;
+               j = i;
+               for (i = 0; i < num; ++i)
+                       klass->methods [j++] = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i));
+       
+               if (tb->interfaces) {
+                       klass->interface_count = mono_array_length (tb->interfaces);
+                       klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
+                       for (i = 0; i < klass->interface_count; ++i) {
+                               MonoReflectionType *iface = mono_type_array_get (tb->interfaces, i);
+                               klass->interfaces [i] = mono_class_from_mono_type (iface->type);
+                               ensure_runtime_vtable (klass->interfaces [i]);
+                       }
+                       klass->interfaces_inited = 1;
                }
+       } else if (klass->generic_class){
+               ensure_generic_class_runtime_vtable (klass);
        }
 
        if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
@@ -9648,6 +9998,7 @@ ensure_runtime_vtable (MonoClass *klass)
                        klass->methods [i]->slot = i;
                
                mono_class_setup_interface_offsets (klass);
+               mono_class_setup_interface_id (klass);
        }
 
        /*
@@ -9721,7 +10072,7 @@ typebuilder_setup_fields (MonoClass *klass)
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionFieldBuilder *fb;
        MonoClassField *field;
-       MonoMemPool *mp = klass->image->mempool;
+       MonoImage *image = klass->image;
        const char *p, *p2;
        int i;
        guint32 len, idx, real_size = 0;
@@ -9740,20 +10091,22 @@ typebuilder_setup_fields (MonoClass *klass)
                return;
        }
        
-       klass->fields = mp_g_new0 (mp, MonoClassField, klass->field.count);
+       klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
+       mono_class_alloc_ext (klass);
+       klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count);
 
        for (i = 0; i < klass->field.count; ++i) {
                fb = mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
-               field->name = mp_string_to_utf8 (mp, fb->name);
+               field->name = mono_string_to_utf8_image (image, fb->name);
                if (fb->attrs) {
-                       field->type = mono_metadata_type_dup (mp, fb->type->type);
+                       field->type = mono_metadata_type_dup (klass->image, monotype_cast (fb->type)->type);
                        field->type->attrs = fb->attrs;
                } else {
-                       field->type = fb->type->type;
+                       field->type = monotype_cast (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->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
                if (fb->offset != -1)
                        field->offset = fb->offset;
                field->parent = klass;
@@ -9763,13 +10116,13 @@ 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->ext->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 = mono_mempool_alloc (mp, len);
-                       memcpy ((gpointer)field->data, p, len);
+                       klass->ext->field_def_values [i].data = mono_image_alloc (image, len);
+                       memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len);
                }
        }
 
@@ -9782,24 +10135,29 @@ typebuilder_setup_properties (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionPropertyBuilder *pb;
-       MonoMemPool *mp = klass->image->mempool;
+       MonoImage *image = klass->image;
+       MonoProperty *properties;
        int i;
 
-       klass->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
-       klass->property.first = 0;
+       if (!klass->ext)
+               klass->ext = image_g_new0 (image, MonoClassExt, 1);
 
-       klass->properties = mp_g_new0 (mp, MonoProperty, klass->property.count);
-       for (i = 0; i < klass->property.count; ++i) {
+       klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
+       klass->ext->property.first = 0;
+
+       properties = image_g_new0 (image, MonoProperty, klass->ext->property.count);
+       klass->ext->properties = properties;
+       for (i = 0; i < klass->ext->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 = mp_string_to_utf8 (mp, pb->name);
+               properties [i].parent = klass;
+               properties [i].attrs = pb->attrs;
+               properties [i].name = mono_string_to_utf8_image (image, pb->name);
                if (pb->get_method)
-                       klass->properties [i].get = pb->get_method->mhandle;
+                       properties [i].get = pb->get_method->mhandle;
                if (pb->set_method)
-                       klass->properties [i].set = pb->set_method->mhandle;
+                       properties [i].set = pb->set_method->mhandle;
 
-               mono_save_custom_attrs (klass->image, &klass->properties [i], pb->cattrs);
+               mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
        }
 }
 
@@ -9810,7 +10168,7 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
        MonoClass *klass;
        int j;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        event->parent = klass;
        event->attrs = eb->attrs;
@@ -9840,35 +10198,40 @@ typebuilder_setup_events (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
        MonoReflectionEventBuilder *eb;
-       MonoMemPool *mp = klass->image->mempool;
+       MonoImage *image = klass->image;
+       MonoEvent *events;
        int i, j;
 
-       klass->event.count = tb->events ? mono_array_length (tb->events) : 0;
-       klass->event.first = 0;
+       if (!klass->ext)
+               klass->ext = image_g_new0 (image, MonoClassExt, 1);
+
+       klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0;
+       klass->ext->event.first = 0;
 
-       klass->events = mp_g_new0 (mp, MonoEvent, klass->event.count);
-       for (i = 0; i < klass->event.count; ++i) {
+       events = image_g_new0 (image, MonoEvent, klass->ext->event.count);
+       klass->ext->events = events;
+       for (i = 0; i < klass->ext->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 = mp_string_to_utf8 (mp, eb->name);
+               events [i].parent = klass;
+               events [i].attrs = eb->attrs;
+               events [i].name = mono_string_to_utf8_image (image, eb->name);
                if (eb->add_method)
-                       klass->events [i].add = eb->add_method->mhandle;
+                       events [i].add = eb->add_method->mhandle;
                if (eb->remove_method)
-                       klass->events [i].remove = eb->remove_method->mhandle;
+                       events [i].remove = eb->remove_method->mhandle;
                if (eb->raise_method)
-                       klass->events [i].raise = eb->raise_method->mhandle;
+                       events [i].raise = eb->raise_method->mhandle;
 
                if (eb->other_methods) {
-                       klass->events [i].other = mp_g_new0 (mp, MonoMethod*, mono_array_length (eb->other_methods) + 1);
+                       events [i].other = image_g_new0 (image, MonoMethod*, mono_array_length (eb->other_methods) + 1);
                        for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
                                MonoReflectionMethodBuilder *mb = 
                                        mono_array_get (eb->other_methods,
                                                                        MonoReflectionMethodBuilder*, j);
-                               klass->events [i].other [j] = mb->mhandle;
+                               events [i].other [j] = mb->mhandle;
                        }
                }
-               mono_save_custom_attrs (klass->image, &klass->events [i], eb->cattrs);
+               mono_save_custom_attrs (klass->image, &events [i], eb->cattrs);
        }
 }
 
@@ -9886,30 +10249,91 @@ remove_instantiations_of (gpointer key,
                return FALSE;
 }
 
+static void
+check_array_for_usertypes (MonoArray *arr)
+{
+       int i;
+
+       if (!arr)
+               return;
+
+       for (i = 0; i < mono_array_length (arr); ++i)
+               CHECK_MONOTYPE (mono_array_get (arr, gpointer, i));
+}
+
 MonoReflectionType*
 mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 {
        MonoClass *klass;
        MonoDomain* domain;
        MonoReflectionType* res;
-       int i;
+       int i, j;
 
        MONO_ARCH_SAVE_REGS;
 
        domain = mono_object_domain (tb);
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
+
+       /*
+        * Check for user defined Type subclasses.
+        */
+       CHECK_MONOTYPE (tb->parent);
+       check_array_for_usertypes (tb->interfaces);
+       if (tb->fields) {
+               for (i = 0; i < mono_array_length (tb->fields); ++i) {
+                       MonoReflectionFieldBuilder *fb = mono_array_get (tb->fields, gpointer, i);
+                       if (fb) {
+                               CHECK_MONOTYPE (fb->type);
+                               check_array_for_usertypes (fb->modreq);
+                               check_array_for_usertypes (fb->modopt);
+                               if (fb->marshal_info && fb->marshal_info->marshaltyperef)
+                                       CHECK_MONOTYPE (fb->marshal_info->marshaltyperef);
+                       }
+               }
+       }
+       if (tb->methods) {
+               for (i = 0; i < mono_array_length (tb->methods); ++i) {
+                       MonoReflectionMethodBuilder *mb = mono_array_get (tb->methods, gpointer, i);
+                       if (mb) {
+                               CHECK_MONOTYPE (mb->rtype);
+                               check_array_for_usertypes (mb->return_modreq);
+                               check_array_for_usertypes (mb->return_modopt);
+                               check_array_for_usertypes (mb->parameters);
+                               if (mb->param_modreq)
+                                       for (j = 0; j < mono_array_length (mb->param_modreq); ++j)
+                                               check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j));
+                               if (mb->param_modopt)
+                                       for (j = 0; j < mono_array_length (mb->param_modopt); ++j)
+                                               check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j));
+                       }
+               }
+       }
+       if (tb->ctors) {
+               for (i = 0; i < mono_array_length (tb->ctors); ++i) {
+                       MonoReflectionCtorBuilder *mb = mono_array_get (tb->ctors, gpointer, i);
+                       if (mb) {
+                               check_array_for_usertypes (mb->parameters);
+                               if (mb->param_modreq)
+                                       for (j = 0; j < mono_array_length (mb->param_modreq); ++j)
+                                               check_array_for_usertypes (mono_array_get (mb->param_modreq, MonoArray*, j));
+                               if (mb->param_modopt)
+                                       for (j = 0; j < mono_array_length (mb->param_modopt); ++j)
+                                               check_array_for_usertypes (mono_array_get (mb->param_modopt, MonoArray*, j));
+                       }
+               }
+       }
 
        mono_save_custom_attrs (klass->image, klass, tb->cattrs);
-       
+
        /* 
         * we need to lock the domain because the lock will be taken inside
         * So, we need to keep the locking order correct.
         */
-       mono_domain_lock (domain);
        mono_loader_lock ();
+       mono_domain_lock (domain);
        if (klass->wastypebuilder) {
-               mono_loader_unlock ();
                mono_domain_unlock (domain);
+               mono_loader_unlock ();
                return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
        }
        /*
@@ -9939,7 +10363,8 @@ 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_mempool (klass->image->mempool, klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type));
+                       mono_class_alloc_ext (klass);
+                       klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtb->type.type));
                }
        }
 
@@ -9978,8 +10403,8 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        if (domain->type_hash && klass->generic_container)
                mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of, klass);
 
-       mono_loader_unlock ();
        mono_domain_unlock (domain);
+       mono_loader_unlock ();
 
        if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
@@ -9995,56 +10420,60 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 void
 mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
 {
-       MonoGenericParam *param;
+       MonoGenericParamFull *param;
        MonoImage *image;
+       MonoClass *pklass;
 
        MONO_ARCH_SAVE_REGS;
 
-       param = g_new0 (MonoGenericParam, 1);
+       param = g_new0 (MonoGenericParamFull, 1);
 
        if (gparam->mbuilder) {
                if (!gparam->mbuilder->generic_container) {
                        MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type;
-                       MonoClass *klass = my_mono_class_from_mono_type (tb->type.type);
-                       gparam->mbuilder->generic_container = mono_mempool_alloc0 (klass->image->mempool, sizeof (MonoGenericContainer));
+                       MonoClass *klass = 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;
+               param->param.owner = gparam->mbuilder->generic_container;
        } else if (gparam->tbuilder) {
-               g_assert (gparam->tbuilder->generic_container);
-               param->owner = gparam->tbuilder->generic_container;
+               if (!gparam->tbuilder->generic_container) {
+                       MonoClass *klass = mono_class_from_mono_type (gparam->tbuilder->type.type);
+                       gparam->tbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
+                       gparam->tbuilder->generic_container->owner.klass = klass;
+               }
+               param->param.owner = gparam->tbuilder->generic_container;
        }
 
-       param->name = mono_string_to_utf8 (gparam->name);
-       param->num = gparam->index;
+       param->info.name = mono_string_to_utf8 (gparam->name);
+       param->param.num = gparam->index;
 
        image = &gparam->tbuilder->module->dynamic_image->image;
-       mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
+       pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);
 
-       MOVING_GC_REGISTER (&param->pklass->reflection_info);
-       param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
+       gparam->type.type = &pklass->byval_arg;
 
-       gparam->type.type = g_new0 (MonoType, 1);
-       gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
-       gparam->type.type->attrs = TYPE_ATTRIBUTE_PUBLIC;
-       gparam->type.type->data.generic_param = param;
+       MOVING_GC_REGISTER (&pklass->reflection_info);
+       pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
 }
 
 MonoArray *
 mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
 {
        MonoDynamicImage *assembly = sig->module->dynamic_image;
-       guint32 na = mono_array_length (sig->arguments);
+       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
        guint32 buflen, i;
        MonoArray *result;
        SigBuffer buf;
 
+       check_array_for_usertypes (sig->arguments);
+
        sigbuffer_init (&buf, 32);
 
        sigbuffer_add_value (&buf, 0x07);
        sigbuffer_add_value (&buf, na);
        for (i = 0; i < na; ++i) {
-               MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
+               MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
                encode_reflection_type (assembly, type, &buf);
        }
 
@@ -10060,16 +10489,18 @@ MonoArray *
 mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
 {
        MonoDynamicImage *assembly = sig->module->dynamic_image;
-       guint32 na = mono_array_length (sig->arguments);
+       guint32 na = sig->arguments ? mono_array_length (sig->arguments) : 0;
        guint32 buflen, i;
        MonoArray *result;
        SigBuffer buf;
 
+       check_array_for_usertypes (sig->arguments);
+
        sigbuffer_init (&buf, 32);
 
        sigbuffer_add_value (&buf, 0x06);
        for (i = 0; i < na; ++i) {
-               MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
+               MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
                encode_reflection_type (assembly, type, &buf);
        }
 
@@ -10127,10 +10558,16 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
                        }
                        handle_class = mono_defaults.methodhandle_class;
                } else {
+                       MonoException *ex = NULL;
                        ref = resolve_object (mb->module->image, obj, &handle_class, NULL);
-                       if (!ref) {
+                       if (!ref)
+                               ex = mono_get_exception_type_load (NULL, NULL);
+                       else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+                               ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
+
+                       if (ex) {
                                g_free (rmb.refs);
-                               mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+                               mono_raise_exception (ex);
                                return;
                        }
                }
@@ -10165,6 +10602,8 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        mb->ilgen = NULL;
 }
 
+#endif /* DISABLE_REFLECTION_EMIT */
+
 void
 mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
 {
@@ -10188,6 +10627,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:
  *
@@ -10195,6 +10636,8 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
  * runtime structure. If HANDLE_CLASS is not NULL, it is set to the class required by 
  * mono_ldtoken. If valid_token is TRUE, assert if it is not found in the token->object
  * mapping table.
+ *
+ * LOCKING: Take the loader lock
  */
 gpointer
 mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
@@ -10203,7 +10646,9 @@ mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean
        MonoObject *obj;
        MonoClass *klass;
 
+       mono_loader_lock ();
        obj = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+       mono_loader_unlock ();
        if (!obj) {
                if (valid_token)
                        g_assert_not_reached ();
@@ -10216,6 +10661,34 @@ mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean
        return resolve_object (image, obj, handle_class, context);
 }
 
+/*
+ * ensure_complete_type:
+ *
+ *   Ensure that KLASS is completed if it is a dynamic type, or references
+ * dynamic types.
+ */
+static void
+ensure_complete_type (MonoClass *klass)
+{
+       if (klass->image->dynamic && !klass->wastypebuilder) {
+               MonoReflectionTypeBuilder *tb = klass->reflection_info;
+
+               mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
+
+               // Asserting here could break a lot of code
+               //g_assert (klass->wastypebuilder);
+       }
+
+       if (klass->generic_class) {
+               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+               int i;
+
+               for (i = 0; i < inst->type_argc; ++i) {
+                       ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]));
+               }
+       }
+}
+
 static gpointer
 resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context)
 {
@@ -10281,7 +10754,24 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                        result = mono_class_inflate_generic_method (result, context);
                *handle_class = mono_defaults.methodhandle_class;
        } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
-               result = ((MonoReflectionField*)obj)->field;
+               MonoClassField *field = ((MonoReflectionField*)obj)->field;
+
+               ensure_complete_type (field->parent);
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type (&field->parent->byval_arg, context);
+                       MonoClass *class = mono_class_from_mono_type (inflated);
+                       MonoClassField *inflated_field;
+                       gpointer iter = NULL;
+                       mono_metadata_free_type (inflated);
+                       while ((inflated_field = mono_class_get_fields (class, &iter))) {
+                               if (!strcmp (field->name, inflated_field->name))
+                                       break;
+                       }
+                       g_assert (inflated_field && !strcmp (field->name, inflated_field->name));
+                       result = inflated_field;
+               } else {
+                       result = field;
+               }
                *handle_class = mono_defaults.fieldhandle_class;
                g_assert (result);
        } else if (strcmp (obj->vtable->klass->name, "FieldBuilder") == 0) {
@@ -10300,7 +10790,7 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                        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);
                }
@@ -10346,7 +10836,7 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                /* TODO: Copy type ? */
                sig->ret = helper->return_type->type;
                for (i = 0; i < nargs; ++i) {
-                       MonoReflectionType *rt = mono_array_get (helper->arguments, MonoReflectionType*, i);
+                       MonoReflectionType *rt = mono_type_array_get (helper->arguments, i);
                        sig->params [i] = rt->type;
                }
 
@@ -10381,7 +10871,7 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                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;
@@ -10408,6 +10898,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[] = {
@@ -10503,14 +11133,19 @@ guint32
 mono_declsec_flags_from_class (MonoClass *klass)
 {
        if (klass->flags & TYPE_ATTRIBUTE_HAS_SECURITY) {
-               if (!klass->declsec_flags) {
-                       guint32 idx = mono_metadata_token_index (klass->type_token);
+               if (!klass->ext || !klass->ext->declsec_flags) {
+                       guint32 idx;
+
+                       idx = mono_metadata_token_index (klass->type_token);
                        idx <<= MONO_HAS_DECL_SECURITY_BITS;
                        idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
+                       mono_loader_lock ();
+                       mono_class_alloc_ext (klass);
+                       mono_loader_unlock ();
                        /* we cache the flags on classes */
-                       klass->declsec_flags = mono_declsec_get_flags (klass->image, idx);
+                       klass->ext->declsec_flags = mono_declsec_get_flags (klass->image, idx);
                }
-               return klass->declsec_flags;
+               return klass->ext->declsec_flags;
        }
        return 0;
 }