2004-09-02 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / reflection.c
index b1b5729409a87e39152999502c31e859d7211c55..dc70fab01662290b310d451fb0e144a6863fddf1 100644 (file)
 #include "mono/utils/mono-digest.h"
 #include "mono/metadata/reflection.h"
 #include "mono/metadata/tabledefs.h"
+#include "mono/metadata/metadata-internals.h"
+#include "mono/metadata/class-internals.h"
 #include "mono/metadata/tokentype.h"
-#include "mono/metadata/appdomain.h"
+#include "mono/metadata/domain-internals.h"
 #include "mono/metadata/opcodes.h"
 #include "mono/metadata/assembly.h"
+#include "mono/metadata/object-internals.h"
 #include <mono/metadata/exception.h>
 #include <stdio.h>
 #include <glib.h>
@@ -60,6 +63,11 @@ typedef struct {
        gpointer *refs;
 } ReflectionMethodBuilder;
 
+typedef struct {
+       guint32 owner;
+       MonoReflectionGenericParam *gparam;
+} GenericParamTableEntry;
+
 const unsigned char table_sizes [64] = {
        MONO_MODULE_SIZE,
        MONO_TYPEREF_SIZE,
@@ -135,6 +143,7 @@ static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, Mon
 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);
@@ -1037,6 +1046,7 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
                dynamic_custom_attrs = g_hash_table_new (NULL, NULL);
 
        g_hash_table_insert (dynamic_custom_attrs, obj, ainfo);
+       ainfo->cached = TRUE;
 }
 
 void
@@ -1050,7 +1060,7 @@ mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
 
 /*
  * idx is the table index of the object
- * type is one of CUSTOM_ATTR_*
+ * type is one of MONO_CUSTOM_ATTR_*
  */
 static void
 mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
@@ -1070,20 +1080,20 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo
        table->rows += count;
        alloc_table (table, table->rows);
        values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
-       idx <<= CUSTOM_ATTR_BITS;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= type;
        for (i = 0; i < count; ++i) {
                cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
                values [MONO_CUSTOM_ATTR_PARENT] = idx;
-               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor);
+               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE);
                type = mono_metadata_token_index (token);
-               type <<= CUSTOM_ATTR_TYPE_BITS;
+               type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
                switch (mono_metadata_token_table (token)) {
                case MONO_TABLE_METHOD:
-                       type |= CUSTOM_ATTR_TYPE_METHODDEF;
+                       type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                        break;
                case MONO_TABLE_MEMBERREF:
-                       type |= CUSTOM_ATTR_TYPE_MEMBERREF;
+                       type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
                        break;
                default:
                        g_warning ("got wrong token in custom attr");
@@ -1122,16 +1132,16 @@ mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token,
                values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;
 
                idx = mono_metadata_token_index (parent_token);
-               idx <<= HAS_DECL_SECURITY_BITS;
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
                switch (mono_metadata_token_table (parent_token)) {
                case MONO_TABLE_TYPEDEF:
-                       idx |= HAS_DECL_SECURITY_TYPEDEF;
+                       idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
                        break;
                case MONO_TABLE_METHOD:
-                       idx |= HAS_DECL_SECURITY_METHODDEF;
+                       idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
                        break;
                case MONO_TABLE_ASSEMBLY:
-                       idx |= HAS_DECL_SECURITY_ASSEMBLY;
+                       idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
                        break;
                default:
                        g_assert_not_reached ();
@@ -1201,18 +1211,29 @@ mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly
                                        name = mono_string_to_utf8 (pb->name);
                                        values [MONO_PARAM_NAME] = string_heap_insert (&assembly->sheap, name);
                                        g_free (name);
-                               }
-                               else
+                               } else {
                                        values [MONO_PARAM_NAME] = 0;
+                               }
                                values += MONO_PARAM_SIZE;
                                if (pb->marshal_info) {
                                        mtable->rows++;
                                        alloc_table (mtable, mtable->rows);
                                        mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE;
-                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_PARAMDEF;
+                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF;
                                        mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, pb->marshal_info);
                                }
                                pb->table_idx = table->next_idx++;
+                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
+                                       guint32 field_type = 0;
+                                       mtable = &assembly->tables [MONO_TABLE_CONSTANT];
+                                       mtable->rows ++;
+                                       alloc_table (mtable, mtable->rows);
+                                       mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE;
+                                       mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS);
+                                       mvalues [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
+                                       mvalues [MONO_CONSTANT_TYPE] = field_type;
+                                       mvalues [MONO_CONSTANT_PADDING] = 0;
+                               }
                        }
                }
        }
@@ -1352,14 +1373,15 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *a
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_METHODIMPL_SIZE;
                values [MONO_METHODIMPL_CLASS] = tb->table_idx;
-               values [MONO_METHODIMPL_BODY] = METHODDEFORREF_METHODDEF | (mb->table_idx << METHODDEFORREF_BITS);
-               tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method);
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+               tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE);
                switch (mono_metadata_token_table (tok)) {
                case MONO_TABLE_MEMBERREF:
-                       tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODREF;
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
                        break;
                case MONO_TABLE_METHOD:
-                       tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODDEF;
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
                        break;
                default:
                        g_assert_not_reached ();
@@ -1405,7 +1427,7 @@ type_get_fully_qualified_name (MonoType *type) {
                name, ta->aname.name,
                ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
                ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral",
-               ta->aname.public_tok_value ? ta->aname.public_tok_value : "null");
+               ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null");
        g_free (name);
        return result;
 }
@@ -1686,7 +1708,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                table->rows ++;
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_CONSTANT_SIZE;
-               values [MONO_CONSTANT_PARENT] = HASCONSTANT_FIEDDEF | (fb->table_idx << HASCONSTANT_BITS);
+               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS);
                values [MONO_CONSTANT_VALUE] = encode_constant (assembly, fb->def_value, &field_type);
                values [MONO_CONSTANT_TYPE] = field_type;
                values [MONO_CONSTANT_PADDING] = 0;
@@ -1712,7 +1734,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                table->rows ++;
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE;
-               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_FIELDSREF;
+               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF;
                values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, fb->marshal_info);
        }
 }
@@ -1797,14 +1819,14 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
                values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
        }
        if (pb->set_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
                values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
        }
 }
 
@@ -1849,21 +1871,21 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON;
                values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
        }
        if (eb->remove_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON;
                values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
        }
        if (eb->raise_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE;
                values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
        }
 }
 
@@ -1905,20 +1927,20 @@ encode_new_constraint (MonoDynamicImage *assembly, guint32 owner)
        alloc_table (table, table->rows);
 
        values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
-       owner <<= CUSTOM_ATTR_BITS;
-       owner |= CUSTOM_ATTR_GENERICPAR;
+       owner <<= MONO_CUSTOM_ATTR_BITS;
+       owner |= MONO_CUSTOM_ATTR_GENERICPAR;
        values [MONO_CUSTOM_ATTR_PARENT] = owner;
 
        token = mono_image_get_methodref_token (assembly, NewConstraintAttr_ctor);
 
        type = mono_metadata_token_index (token);
-       type <<= CUSTOM_ATTR_TYPE_BITS;
+       type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
        switch (mono_metadata_token_table (token)) {
        case MONO_TABLE_METHOD:
-               type |= CUSTOM_ATTR_TYPE_METHODDEF;
+               type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                break;
        case MONO_TABLE_MEMBERREF:
-               type |= CUSTOM_ATTR_TYPE_MEMBERREF;
+               type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
                break;
        default:
                g_warning ("got wrong token in custom attr");
@@ -1979,6 +2001,25 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam
 
 static void
 mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
+{
+       GenericParamTableEntry *entry;
+
+       /*
+        * The GenericParam table must be sorted according to the `owner' field.
+        * We need to do this sorting prior to writing the GenericParamConstraint
+        * table, since we have to use the final GenericParam table indices there
+        * and they must also be sorted.
+        */
+
+       entry = g_new0 (GenericParamTableEntry, 1);
+       entry->owner = owner;
+       entry->gparam = gparam;
+
+       g_ptr_array_add (assembly->gen_params, entry);
+}
+
+static void
+write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry)
 {
        MonoDynamicTable *table;
        MonoGenericParam *param;
@@ -1989,12 +2030,12 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        table_idx = table->next_idx ++;
        values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
 
-       param = gparam->type.type->data.generic_param;
+       param = entry->gparam->type.type->data.generic_param;
 
-       values [MONO_GENERICPARAM_OWNER] = owner;
-       if (gparam->has_value_type)
+       values [MONO_GENERICPARAM_OWNER] = entry->owner;
+       if (entry->gparam->has_value_type)
                values [MONO_GENERICPARAM_FLAGS] = 0x18;
-       else if (gparam->has_reference_type)
+       else if (entry->gparam->has_reference_type)
                values [MONO_GENERICPARAM_FLAGS] = 0x04;
        else
                values [MONO_GENERICPARAM_FLAGS] = 0x00;
@@ -2002,7 +2043,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
        values [MONO_GENERICPARAM_KIND] = 0;
 
-       encode_constraints (gparam, table_idx, assembly);
+       encode_constraints (entry->gparam, table_idx, assembly);
 }
 
 static guint32
@@ -2026,8 +2067,8 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
                values = table->values + token * MONO_MODULEREF_SIZE;
                values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
 
-               token <<= RESOLTION_SCOPE_BITS;
-               token |= RESOLTION_SCOPE_MODULEREF;
+               token <<= MONO_RESOLTION_SCOPE_BITS;
+               token |= MONO_RESOLTION_SCOPE_MODULEREF;
                g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
 
                return token;
@@ -2069,8 +2110,8 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
        } else {
                values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
        }
-       token <<= RESOLTION_SCOPE_BITS;
-       token |= RESOLTION_SCOPE_ASSEMBLYREF;
+       token <<= MONO_RESOLTION_SCOPE_BITS;
+       token |= MONO_RESOLTION_SCOPE_ASSEMBLYREF;
        g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
        return token;
 }
@@ -2118,7 +2159,7 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type)
                values [MONO_TYPESPEC_SIGNATURE] = token;
        }
 
-       token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
        g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
@@ -2151,7 +2192,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        if ((klass->image == &assembly->image) &&
            (type->type != MONO_TYPE_VAR) && (type->type != MONO_TYPE_MVAR)) {
                MonoReflectionTypeBuilder *tb = klass->reflection_info;
-               token = TYPEDEFORREF_TYPEDEF | (tb->table_idx << TYPEDEFORREF_BITS);
+               token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
                mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
                return token;
        }
@@ -2159,8 +2200,8 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        if (klass->nested_in) {
                enclosing = mono_image_typedef_or_ref (assembly, &klass->nested_in->byval_arg);
                /* get the typeref idx of the enclosing type */
-               enclosing >>= TYPEDEFORREF_BITS;
-               scope = (enclosing << RESOLTION_SCOPE_BITS) | RESOLTION_SCOPE_TYPEREF;
+               enclosing >>= MONO_TYPEDEFORREF_BITS;
+               scope = (enclosing << MONO_RESOLTION_SCOPE_BITS) | MONO_RESOLTION_SCOPE_TYPEREF;
        } else {
                scope = resolution_scope_from_image (assembly, klass->image);
        }
@@ -2172,7 +2213,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
                values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
                values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
        }
-       token = TYPEDEFORREF_TYPEREF | (table->next_idx << TYPEDEFORREF_BITS); /* typeref */
+       token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
        g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
@@ -2194,29 +2235,29 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
        guint32 parent;
 
        parent = mono_image_typedef_or_ref (assembly, type);
-       switch (parent & TYPEDEFORREF_MASK) {
-       case TYPEDEFORREF_TYPEREF:
-               pclass = MEMBERREF_PARENT_TYPEREF;
+       switch (parent & MONO_TYPEDEFORREF_MASK) {
+       case MONO_TYPEDEFORREF_TYPEREF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEREF;
                break;
-       case TYPEDEFORREF_TYPESPEC:
-               pclass = MEMBERREF_PARENT_TYPESPEC;
+       case MONO_TYPEDEFORREF_TYPESPEC:
+               pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
                break;
-       case TYPEDEFORREF_TYPEDEF:
-               pclass = MEMBERREF_PARENT_TYPEDEF;
+       case MONO_TYPEDEFORREF_TYPEDEF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
                break;
        default:
                g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
                return 0;
        }
        /* extract the index */
-       parent >>= TYPEDEFORREF_BITS;
+       parent >>= MONO_TYPEDEFORREF_BITS;
 
        table = &assembly->tables [MONO_TABLE_MEMBERREF];
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
                values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
                values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
                values [MONO_MEMBERREF_SIGNATURE] = sig;
        }
@@ -2246,29 +2287,15 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina
                                     const gchar *name, guint32 sig)
 {
        MonoDynamicTable *table;
-       guint32 parent, token;
+       guint32 token;
        guint32 *values;
        
        table = &assembly->tables [MONO_TABLE_MEMBERREF];
 
-       parent = mono_metadata_token_index (original);
-       parent <<= MEMBERREF_PARENT_BITS;
-       switch (mono_metadata_token_table (original)) {
-       case MONO_TABLE_METHOD:
-               parent |= MEMBERREF_PARENT_METHODDEF;
-               break;
-       case MONO_TABLE_MEMBERREF:
-               parent |= MEMBERREF_PARENT_TYPEREF;
-               break;
-       default:
-               g_warning ("got wrong token in varargs method token");
-               return 0;
-       }
-
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
                values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = parent;
+               values [MONO_MEMBERREF_CLASS] = original;
                values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
                values [MONO_MEMBERREF_SIGNATURE] = sig;
        }
@@ -2327,7 +2354,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
        if (token)
                return token;
        g_assert (f->field->parent);
-       type = f->field->generic_type ? f->field->generic_type : f->field->type;
+       type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type;
        token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg, 
                f->field->name,  fieldref_encode_signature (assembly, type));
        g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
@@ -2353,7 +2380,7 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmetho
        /*
         * FIXME: vararg, explicit_this, differenc call_conv values...
         */
-       mono_metadata_encode_value (0xa, p, &p); /// FIXME FIXME FIXME
+       mono_metadata_encode_value (0xa, p, &p); /* FIXME FIXME FIXME */
        mono_metadata_encode_value (nparams, p, &p);
 
        for (i = 0; i < nparams; i++)
@@ -2391,10 +2418,10 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
 
        switch (mono_metadata_token_table (mtoken)) {
        case MONO_TABLE_MEMBERREF:
-               mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODREF;
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
                break;
        case MONO_TABLE_METHOD:
-               mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODDEF;
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
                break;
        default:
                g_assert_not_reached ();
@@ -2441,6 +2468,19 @@ mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
        return token;
 }
 
+static guint32
+mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
+{
+       MonoMethodInflated *imethod = (MonoMethodInflated *) m;
+       guint32 sig, token;
+
+       sig = method_encode_signature (assembly, imethod->declaring->signature);
+       token = mono_image_get_memberref_token (
+               assembly, &m->klass->byval_arg, m->name, sig);
+
+       return token;
+}
+
 static guint32
 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb)
 {
@@ -2490,7 +2530,7 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
                values [MONO_TYPESPEC_SIGNATURE] = token;
        }
 
-       token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
        g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
@@ -2515,17 +2555,17 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        sig = fieldref_encode_signature (assembly, fb->type->type);
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
-       g_assert ((parent & TYPEDEFORREF_MASK) == TYPEDEFORREF_TYPESPEC);
+       g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
        
-       pclass = MEMBERREF_PARENT_TYPESPEC;
-       parent >>= TYPEDEFORREF_BITS;
+       pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
+       parent >>= MONO_TYPEDEFORREF_BITS;
 
        table = &assembly->tables [MONO_TABLE_MEMBERREF];
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
                values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
                values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
                values [MONO_MEMBERREF_SIGNATURE] = sig;
        }
@@ -2714,7 +2754,8 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
         * if we have explicitlayout or sequentiallayouts, output data in the
         * ClassLayout table.
         */
-       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) && (tb->class_size != -1)) {
+       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
+           ((tb->class_size > 0) || (tb->packing_size > 0))) {
                table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
                table->rows++;
                alloc_table (table, table->rows);
@@ -2739,19 +2780,6 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                }
        }
 
-       /* handle generic parameters */
-       if (tb->generic_params) {
-               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
-               table->rows += mono_array_length (tb->generic_params);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
-                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
-
-                       mono_image_get_generic_param_info (
-                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
-               }
-       }
-
        /* handle fields */
        if (tb->fields) {
                table = &assembly->tables [MONO_TABLE_FIELD];
@@ -2812,6 +2840,19 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                                mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
        }
 
+       /* handle generic parameters */
+       if (tb->generic_params) {
+               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+               table->rows += mono_array_length (tb->generic_params);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
+                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
+
+                       mono_image_get_generic_param_info (
+                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
+               }
+       }
+
        mono_image_add_decl_security (assembly, 
                                                                  mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx),
                                                                  tb->permissions);
@@ -2879,7 +2920,7 @@ params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo) {
                pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i);
                if (!pb)
                        continue;
-               mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PARAMDEF, pb->cattrs);
+               mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs);
        }
 }
 
@@ -2887,33 +2928,33 @@ static void
 type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) {
        int i;
        
-       mono_image_add_cattrs (assembly, tb->table_idx, CUSTOM_ATTR_TYPEDEF, tb->cattrs);
+       mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs);
        if (tb->fields) {
                for (i = 0; i < tb->num_fields; ++i) {
                        MonoReflectionFieldBuilder* fb;
                        fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i);
-                       mono_image_add_cattrs (assembly, fb->table_idx, CUSTOM_ATTR_FIELDDEF, fb->cattrs);
+                       mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs);
                }
        }
        if (tb->events) {
                for (i = 0; i < mono_array_length (tb->events); ++i) {
                        MonoReflectionEventBuilder* eb;
                        eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
-                       mono_image_add_cattrs (assembly, eb->table_idx, CUSTOM_ATTR_EVENT, eb->cattrs);
+                       mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs);
                }
        }
        if (tb->properties) {
                for (i = 0; i < mono_array_length (tb->properties); ++i) {
                        MonoReflectionPropertyBuilder* pb;
                        pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
-                       mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PROPERTY, pb->cattrs);
+                       mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs);
                }
        }
        if (tb->ctors) {
                for (i = 0; i < mono_array_length (tb->ctors); ++i) {
                        MonoReflectionCtorBuilder* cb;
                        cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i);
-                       mono_image_add_cattrs (assembly, cb->table_idx, CUSTOM_ATTR_METHODDEF, cb->cattrs);
+                       mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs);
                        params_add_cattrs (assembly, cb->pinfo);
                }
        }
@@ -2922,7 +2963,7 @@ type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) {
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder* mb;
                        mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_METHODDEF, mb->cattrs);
+                       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs);
                        params_add_cattrs (assembly, mb->pinfo);
                }
        }
@@ -2937,7 +2978,7 @@ static void
 module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *mb) {
        int i;
        
-       mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_MODULE, mb->cattrs);
+       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_MODULE, mb->cattrs);
        
        /* no types in the module */
        if (!mb->types)
@@ -3023,9 +3064,9 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        values [MONO_EXP_TYPE_FLAGS] = klass->flags;
        values [MONO_EXP_TYPE_TYPEDEF] = klass->type_token;
        if (klass->nested_in)
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_EXP_TYPE;
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
        else
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_FILE;
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE;
        values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
        values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
 
@@ -3133,6 +3174,30 @@ compare_nested (const void *a, const void *b)
        return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
 }
 
+static int
+compare_genericparam (const void *a, const void *b)
+{
+       const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
+       const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
+
+       return (*a_entry)->owner - (*b_entry)->owner;
+}
+
+static void
+pad_heap (MonoDynamicStream *sh)
+{
+       if (sh->index & 3) {
+               int sz = 4 - (sh->index & 3);
+               memset (sh->data + sh->index, 0, sz);
+               sh->index += sz;
+       }
+}
+
+static struct StreamDesc {
+       const char *name;
+       MonoDynamicStream *stream;
+} stream_desc [5];
+
 /*
  * build_compressed_metadata() fills in the blob of data that represents the 
  * raw metadata as it will be saved in the PE file. The five streams are output 
@@ -3156,10 +3221,11 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        MonoImage *meta;
        unsigned char *p;
 
-       struct StreamDesc {
-               const char *name;
-               MonoDynamicStream *stream;
-       } stream_desc [5];
+       qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
+       for (i = 0; i < assembly->gen_params->len; i++){
+               GenericParamTableEntry *entry = g_ptr_array_index (assembly->gen_params, i);
+               write_generic_param_entry (assembly, entry);
+       }
 
        stream_desc[0].name  = "#~"; stream_desc[0].stream = &assembly->tstream;
        stream_desc[1].name  = "#Strings"; stream_desc[1].stream = &assembly->sheap;
@@ -3173,12 +3239,18 @@ 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_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM);
        
        /* Compute table sizes */
        /* the MonoImage has already been created in mono_image_basic_init() */
        meta = &assembly->image;
-       
+
+       /* sizes should be multiple of 4 */
+       pad_heap (&assembly->blob);
+       pad_heap (&assembly->guid);
+       pad_heap (&assembly->sheap);
+       pad_heap (&assembly->us);
+
        /* Setup the info used by compute_sizes () */
        meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
        meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
@@ -3203,6 +3275,9 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        }
        heapt_size += 24; /* #~ header size */
        heapt_size += ntables * 4;
+       /* make multiple of 4 */
+       heapt_size += 3;
+       heapt_size &= ~3;
        meta_size += heapt_size;
        meta->raw_metadata = g_malloc0 (meta_size);
        p = meta->raw_metadata;
@@ -3297,6 +3372,7 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        if (table->rows)
                qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
 
+
        /* compress the tables */
        for (i = 0; i < 64; i++){
                int row, col;
@@ -3411,7 +3487,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_type);
+                               g_assert (f->generic_info);
                                continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
                                continue;
@@ -3457,8 +3533,8 @@ fixup_cattrs (MonoDynamicImage *assembly)
                values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
 
                type = values [MONO_CUSTOM_ATTR_TYPE];
-               if ((type & CUSTOM_ATTR_TYPE_MASK) == CUSTOM_ATTR_TYPE_METHODDEF) {
-                       idx = type >> CUSTOM_ATTR_TYPE_BITS;
+               if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
+                       idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
                        token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
                        ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
                        g_assert (ctor);
@@ -3466,7 +3542,7 @@ fixup_cattrs (MonoDynamicImage *assembly)
                        if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
                                MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
                                idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
-                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << CUSTOM_ATTR_TYPE_BITS) | CUSTOM_ATTR_TYPE_METHODDEF;
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                        }
                }
        }
@@ -3522,7 +3598,7 @@ assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assemb
                g_free (name);
                idx = table->next_idx++;
                rsrc->offset = 0;
-               idx = IMPLEMENTATION_FILE | (idx << IMPLEMENTATION_BITS);
+               idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
        } else {
                char sizebuf [4];
                offset = mono_array_length (rsrc->data);
@@ -3672,7 +3748,7 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
                                int len = mono_array_length (file_module->resources);
                                for (j = 0; j < len; ++j) {
                                        MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j);
-                                       assembly_add_resource_manifest (file_module, assembly, res, IMPLEMENTATION_FILE | (module_index << IMPLEMENTATION_BITS));
+                                       assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS));
                                }
                        }
                }
@@ -3775,7 +3851,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
         * table->rows is already set above and in mono_image_fill_module_table.
         */
        /* add all the custom attributes at the end, once all the indexes are stable */
-       mono_image_add_cattrs (assembly, 1, CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
+       mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
 
        module_add_cattrs (assembly, moduleb);
 
@@ -3837,15 +3913,13 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
                                MonoArray *opt_param_types)
 {
        MonoClass *klass;
-       guint32 original_token, token = 0;
-
-       original_token = mono_image_create_token (assembly, obj);
+       guint32 token = 0;
 
        klass = obj->vtable->klass;
        if (strcmp (klass->name, "MonoMethod") == 0) {
                MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
                MonoMethodSignature *sig, *old;
-               guint32 sig_token;
+               guint32 sig_token, parent;
                int nargs, i;
 
                g_assert (opt_param_types && (method->signature->sentinelpos >= 0));
@@ -3872,21 +3946,34 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
                        sig->params [old->param_count + i] = rt->type;
                }
 
+               parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
+               g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
+               parent >>= MONO_TYPEDEFORREF_BITS;
+
+               parent <<= MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_TYPEREF;
+
                sig_token = method_encode_signature (assembly, sig);
                token = mono_image_get_varargs_method_token (
-                       assembly, original_token, method->name, sig_token);
+                       assembly, parent, method->name, sig_token);
        } else if (strcmp (klass->name, "MethodBuilder") == 0) {
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                ReflectionMethodBuilder rmb;
-               guint32 sig;
+               guint32 parent, sig;
        
                reflection_methodbuilder_from_method_builder (&rmb, mb);
                rmb.opt_types = opt_param_types;
 
                sig = method_builder_encode_signature (assembly, &rmb);
 
+               parent = mono_image_create_token (assembly, obj, TRUE);
+               g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
+
+               parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_METHODDEF;
+
                token = mono_image_get_varargs_method_token (
-                       assembly, original_token, mono_string_to_utf8 (rmb.name), sig);
+                       assembly, parent, mono_string_to_utf8 (rmb.name), sig);
        } else
                g_error ("requested method token for %s\n", klass->name);
 
@@ -3910,7 +3997,8 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
  *     TypeBuilder
  */
 guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
+                        gboolean create_methodspec)
 {
        MonoClass *klass;
        guint32 token = 0;
@@ -3962,7 +4050,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                        strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
                if (m->method->signature->is_inflated) {
-                       token = mono_image_get_methodspec_token (assembly, m->method);
+                       if (create_methodspec)
+                               token = mono_image_get_methodspec_token (
+                                       assembly, m->method);
+                       else
+                               token = mono_image_get_inflated_method_token (
+                                       assembly, m->method);
                } else if (m->method->signature->generic_param_count) {
                        g_assert_not_reached ();
                } else if ((m->method->klass->image == &assembly->image) &&
@@ -3989,7 +4082,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
        }
        else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField *)obj;
-               if ((f->klass->image == &assembly->image) && !f->field->generic_type) {
+               if ((f->klass->image == &assembly->image) && !f->field->generic_info) {
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
@@ -4037,12 +4130,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly,
        MonoDynamicImage *image;
        int i;
 
-       /*
-        * We need to use the current ms version or the ms runtime it won't find
-        * the support dlls. D'oh!
-        * const char *version = "mono-" VERSION;
-        */
-       const char *version = "v1.0.3705";
+       const char *version = mono_get_runtime_version ();
 
 #if HAVE_BOEHM_GC
        image = GC_MALLOC (sizeof (MonoDynamicImage));
@@ -4071,6 +4159,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly,
        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 = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
+       image->gen_params = g_ptr_array_new ();
 
        string_heap_init (&image->sheap);
        mono_image_add_stream_data (&image->us, "", 1);
@@ -4553,23 +4642,25 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb) {
        size &= ~(VIRT_ALIGN - 1);
        header->nt.pe_image_size = GUINT32_FROM_LE (size);
 
-       //
+       /*
        // Translate the PEFileKind value to the value expected by the Windows loader
-       //
+       */
        {
-               short kind = assemblyb->pekind;
+               short kind;
 
-               //
+               /*
+               // PEFileKinds.Dll == 1
                // PEFileKinds.ConsoleApplication == 2
                // PEFileKinds.WindowApplication == 3
                //
                // need to get:
                //     IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
                 //     IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
-               if (kind == 2)
-                       kind = 3;
-               else if (kind == 3)
+               */
+               if (assemblyb->pekind == 3)
                        kind = 2;
+               else
+                       kind = 3;
                
                header->nt.pe_subsys_required = GUINT16_FROM_LE (kind);
        }    
@@ -4841,7 +4932,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
                 * we don't know which module it belongs to, since that is only 
                 * determined at assembly save time.
                 */
-               //image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image;
+               /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
                image = create_dynamic_mono_image (ab->dynamic_assembly, mono_string_to_utf8 (ab->name), mono_string_to_utf8 (moduleb->module.fqname));
 
                moduleb->module.image = &image->image;
@@ -4924,7 +5015,7 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
        name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
 
-       // Check whenever the row has a corresponding row in the moduleref table
+       /* Check whenever the row has a corresponding row in the moduleref table */
        table = &image->tables [MONO_TABLE_MODULEREF];
        for (i = 0; i < table->rows; ++i) {
                name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME);
@@ -5079,7 +5170,7 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                return res;
        }
        if (klass->reflection_info && !klass->wastypebuilder) {
-               //g_assert_not_reached ();
+               /* g_assert_not_reached (); */
                /* should this be considered an error condition? */
                if (!type->byref) {
                        mono_domain_unlock (domain);
@@ -5152,7 +5243,10 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res->klass = klass;
        res->field = field;
        res->name = mono_string_new (domain, field->name);
-       res->attrs = field->type->attrs;
+       if (field->generic_info)
+               res->attrs = field->generic_info->generic_type->attrs;
+       else
+               res->attrs = field->type->attrs;
        res->type = mono_type_get_object (domain, field->type);
        CACHE_OBJECT (field, res, klass);
        return res;
@@ -5265,7 +5359,7 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        memset (assembly, 0, sizeof (MonoAssemblyName));
        assembly->name = p;
        assembly->culture = "";
-       assembly->public_tok_value = NULL;
+       memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
 
        while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
                p++;
@@ -5313,10 +5407,15 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
                        if (strncmp (p, "null", 4) == 0) {
                                p += 4;
                        } else {
-                               assembly->public_tok_value = p;
+                               int len;
+                               gchar *start = p;
                                while (*p && *p != ',') {
                                        p++;
                                }
+                               len = (p - start + 1);
+                               if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH)
+                                       len = MONO_PUBLIC_KEY_TOKEN_LENGTH;
+                               g_strlcpy (assembly->public_key_token, start, len);
                        }
                } else {
                        while (*p && *p != ',')
@@ -5548,7 +5647,7 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
        if (!mono_domain_has_type_resolve (mono_domain_get ()))
                return NULL;
        
-       // Reconstruct the type name
+       /* Reconstruct the type name */
        fullName = g_string_new ("");
        if (info->name_space && (info->name_space [0] != '\0'))
                g_string_printf (fullName, "%s.%s", info->name_space, info->name);
@@ -5625,15 +5724,17 @@ mono_reflection_type_from_name (char *name, MonoImage *image)
 
        if (info.assembly.name) {
                assembly = mono_assembly_loaded (&info.assembly);
-               /* do we need to load if it's not already loaded? */
                if (!assembly) {
-                       g_free (tmp);
-                       g_list_free (info.modifiers);
-                       g_list_free (info.nested);
-                       return NULL;
+                       /* then we must load the assembly ourselve - see #60439 */
+                       assembly = mono_assembly_load (&info.assembly, NULL, NULL);
+                       if (!assembly) {
+                               g_free (tmp);
+                               g_list_free (info.modifiers);
+                               g_list_free (info.nested);
+                               return NULL;
+                       }
                }
-               else
-                       image = assembly->image;
+               image = assembly->image;
        } else if (image == NULL) {
                image = mono_defaults.corlib;
        }
@@ -5823,6 +5924,7 @@ handle_type:
                                }
                                break;
                        case MONO_TYPE_CLASS:
+                       case MONO_TYPE_OBJECT:
                        case MONO_TYPE_STRING:
                                for (i = 0; i < alen; i++) {
                                        MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
@@ -5985,11 +6087,11 @@ create_custom_attr (MonoImage *image, MonoMethod *method,
                        type_name [type_len] = 0;
                        named += type_len;
                        /* FIXME: lookup the type and check type consistency */
+               } else if (data_type == MONO_TYPE_SZARRAY && (named_type == 0x54 || named_type == 0x53)) {
+                       /* this seems to be the type of the element of the array */
+                       /* g_print ("skipping 0x%02x after prop\n", *named); */
+                       named++;
                }
-               else
-                       if (data_type == MONO_TYPE_SZARRAY)
-                               /* The spec does not mention this */
-                               named ++;
                name_len = mono_metadata_decode_blob_size (named, &named);
                name = g_malloc (name_len + 1);
                memcpy (name, named, name_len);
@@ -5998,9 +6100,9 @@ create_custom_attr (MonoImage *image, MonoMethod *method,
                if (named_type == 0x53) {
                        MonoClassField *field = mono_class_get_field_from_name (mono_object_class (attr), name);
                        void *val = load_cattr_value (image, field->type, named, &named);
-                               mono_field_set_value (attr, field, val);
-                               if (!type_is_reference (field->type))
-                                       g_free (val);
+                       mono_field_set_value (attr, field, val);
+                       if (!type_is_reference (field->type))
+                               g_free (val);
                } else if (named_type == 0x54) {
                        MonoProperty *prop;
                        void *pparams [1];
@@ -6067,12 +6169,12 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
        ainfo->image = image;
        for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) {
                mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
-               mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
-               switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
-               case CUSTOM_ATTR_TYPE_METHODDEF:
+               mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
+               switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
+               case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
                        mtoken |= MONO_TOKEN_METHOD_DEF;
                        break;
-               case CUSTOM_ATTR_TYPE_MEMBERREF:
+               case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
                        mtoken |= MONO_TOKEN_MEMBER_REF;
                        break;
                default:
@@ -6100,8 +6202,8 @@ mono_custom_attrs_from_method (MonoMethod *method)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, method)))
                return cinfo;
        idx = find_method_index (method);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_METHODDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_METHODDEF;
        return mono_custom_attrs_from_index (method->klass->image, idx);
 }
 
@@ -6114,8 +6216,8 @@ mono_custom_attrs_from_class (MonoClass *klass)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass)))
                return cinfo;
        idx = mono_metadata_token_index (klass->type_token);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_TYPEDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_TYPEDEF;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -6128,8 +6230,8 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, assembly)))
                return cinfo;
        idx = 1; /* there is only one assembly */
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_ASSEMBLY;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
        return mono_custom_attrs_from_index (assembly->image, idx);
 }
 
@@ -6142,8 +6244,8 @@ mono_custom_attrs_from_module (MonoImage *image)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, image)))
                return cinfo;
        idx = 1; /* there is only one module */
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_MODULE;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_MODULE;
        return mono_custom_attrs_from_index (image, idx);
 }
 
@@ -6156,8 +6258,8 @@ mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, property)))
                return cinfo;
        idx = find_property_index (klass, property);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_PROPERTY;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PROPERTY;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -6170,8 +6272,8 @@ mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, event)))
                return cinfo;
        idx = find_event_index (klass, event);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_EVENT;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_EVENT;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -6184,8 +6286,8 @@ mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
                return cinfo;
        idx = find_field_index (klass, field);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_FIELDDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_FIELDDEF;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -6211,7 +6313,7 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
        if (method->klass->generic_inst || method->klass->gen_params ||
            method->signature->generic_param_count) {
-               // FIXME FIXME FIXME
+               /* FIXME FIXME FIXME */
                return NULL;
        }
 
@@ -6234,8 +6336,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
        if (!found)
                return NULL;
        idx = i;
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_PARAMDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PARAMDEF;
        return mono_custom_attrs_from_index (image, idx);
 }
 
@@ -6295,7 +6397,8 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
 
        if (cinfo) {
                result = mono_custom_attrs_construct (cinfo);
-               mono_custom_attrs_free (cinfo);
+               if (!cinfo->cached)
+                       mono_custom_attrs_free (cinfo);
        } else {
                klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
                result = mono_array_new (mono_domain_get (), klass, 0);
@@ -6386,10 +6489,21 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
        }
 }
 
+/*
+ * Encode a value in a custom attribute stream of bytes.
+ * The value to encode is either supplied as an object in argument val
+ * (valuetypes are boxed), or as a pointer to the data in the
+ * argument argval.
+ * @type represents the type of the value
+ * @buffer is the start of the buffer
+ * @p the current position in the buffer
+ * @buflen contains the size of the buffer and is used to return the new buffer size
+ * if this needs to be realloced.
+ * @retbuffer and @retp return the start and the position of the buffer
+ */
 static void
-encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg)
+encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval)
 {
-       char *argval;
        MonoTypeEnum simple_type;
        
        if ((p-buffer) + 10 >= *buflen) {
@@ -6399,7 +6513,8 @@ encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuf
                p = newbuf + (p-buffer);
                buffer = newbuf;
        }
-       argval = ((char*)arg + sizeof (MonoObject));
+       if (!argval)
+               argval = ((char*)arg + sizeof (MonoObject));
        simple_type = type->type;
 handle_enum:
        switch (simple_type) {
@@ -6488,7 +6603,7 @@ handle_type:
        }
        case MONO_TYPE_SZARRAY: {
                int len, i;
-               MonoClass *eclass;
+               MonoClass *eclass, *arg_eclass;
 
                if (!arg) {
                        *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
@@ -6502,8 +6617,18 @@ handle_type:
                *retp = p;
                *retbuffer = buffer;
                eclass = type->data.klass;
-               for (i = 0; i < len; ++i) {
-                       encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i));
+               arg_eclass = mono_object_class (arg)->element_class;
+               if (eclass->valuetype && arg_eclass->valuetype) {
+                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+                       int elsize = mono_class_array_element_size (eclass);
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr);
+                               elptr += elsize;
+                       }
+               } else {
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL);
+                       }
                }
                break;
        }
@@ -6589,7 +6714,7 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
        *p++ = 0;
        for (i = 0; i < sig->param_count; ++i) {
                arg = mono_array_get (ctorArgs, MonoObject*, i);
-               encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg);
+               encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL);
        }
        i = 0;
        if (properties)
@@ -6650,7 +6775,7 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
                        mono_metadata_encode_value (len, p, &p);
                        memcpy (p, pname, len);
                        p += len;
-                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i));
+                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i), NULL);
                        g_free (pname);
                }
        }
@@ -6687,12 +6812,14 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
                                g_free (str);
                        } else {
                                mono_metadata_encode_value (ftype->type, p, &p);
+                               if (ftype->type == MONO_TYPE_SZARRAY)
+                                       mono_metadata_encode_value (ftype->data.klass->this_arg.type, p, &p);
                        }
                        len = strlen (fname);
                        mono_metadata_encode_value (len, p, &p);
                        memcpy (p, fname, len);
                        p += len;
-                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i));
+                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i), NULL);
                        g_free (fname);
                }
        }
@@ -6723,10 +6850,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = g_new0 (MonoClass, 1);
-
-       klass->image = &tb->module->dynamic_image->image;
-
        if (tb->parent) {
                /* check so we can compile corlib correctly */
                if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
@@ -6737,6 +6860,22 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        } else
                parent = NULL;
        
+       /* the type has already being created: it means we just have to change the parent */
+       if (tb->type.type) {
+               klass = mono_class_from_mono_type (tb->type.type);
+               klass->parent = NULL;
+               /* fool mono_class_setup_parent */
+               g_free (klass->supertypes);
+               klass->supertypes = NULL;
+               mono_class_setup_parent (klass, parent);
+               mono_class_setup_mono_type (klass);
+               return;
+       }
+       
+       klass = g_new0 (MonoClass, 1);
+
+       klass->image = &tb->module->dynamic_image->image;
+
        klass->inited = 1; /* we lie to the runtime */
        klass->name = mono_string_to_utf8 (tb->name);
        klass->name_space = mono_string_to_utf8 (tb->nspace);
@@ -6981,19 +7120,19 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                                                 num_clauses);
                }
 
-               if (rmb->generic_params) {
-                       int count = mono_array_length (rmb->generic_params);
-                       header->gen_params = g_new0 (MonoGenericParam, count);
-                       for (i = 0; i < count; i++) {
-                               MonoReflectionGenericParam *gp =
-                                       mono_array_get (rmb->generic_params,
-                                                       MonoReflectionGenericParam*, i);
+               pm->header = header;
+       }
+
+       if (rmb->generic_params) {
+               int count = mono_array_length (rmb->generic_params);
+               pm->gen_params = g_new0 (MonoGenericParam, count);
+               for (i = 0; i < count; i++) {
+                       MonoReflectionGenericParam *gp =
+                               mono_array_get (rmb->generic_params,
+                                               MonoReflectionGenericParam*, i);
 
-                               header->gen_params [i] = *gp->type.type->data.generic_param;
-                       }
+                       pm->gen_params [i] = *gp->type.type->data.generic_param;
                }
-
-               pm->header = header;
        }
 
        if (rmb->refs) {
@@ -7125,14 +7264,13 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        if (fb->def_value) {
                MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-               field->def_value = g_new0 (MonoConstant, 1);
-               idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+               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->def_value->value = g_malloc (len);
-               memcpy (field->def_value->value, p, len);
+               field->data = g_malloc (len);
+               memcpy (field->data, p, len);
        }
 
        return field;
@@ -7144,7 +7282,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
 {
        MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
-       MonoGenericInst *ginst;
+       MonoGenericInst *ginst, *cached;
        MonoDomain *domain;
        MonoType *geninst;
        int icount, i;
@@ -7191,20 +7329,22 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
                ginst->generic_type = kginst->generic_type;
        }
 
-       geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
-       if (geninst) {
+       geninst = g_new0 (MonoType, 1);
+       geninst->type = MONO_TYPE_GENERICINST;
+
+       cached = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+       if (cached) {
                g_free (ginst);
                mono_loader_unlock ();
+               geninst->data.generic_inst = cached;
                return geninst;
        }
 
+       geninst->data.generic_inst = ginst;
+
        ginst->context = g_new0 (MonoGenericContext, 1);
        ginst->context->ginst = ginst;
 
-       geninst = g_new0 (MonoType, 1);
-       geninst->type = MONO_TYPE_GENERICINST;
-       geninst->data.generic_inst = ginst;
-
        if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
                tb = (MonoReflectionTypeBuilder *) type;
 
@@ -7239,7 +7379,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
 
        mono_class_create_generic (ginst);
 
-       g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+       g_hash_table_insert (klass->image->generic_inst_cache, ginst, ginst);
 
        mono_loader_unlock ();
 
@@ -7318,6 +7458,8 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                gmethod->mtype_argv [i] = garg->type;
        }
 
+       gmethod->reflection_info = rmethod;
+
        context = g_new0 (MonoGenericContext, 1);
        context->ginst = method->klass->generic_inst;
        context->gmethod = gmethod;
@@ -7346,7 +7488,7 @@ inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoOb
 
        for (i = 0; i < gmethod->mtype_argc; i++) {
                MonoMethodNormal *mn = (MonoMethodNormal *) method;
-               MonoGenericParam *gparam = &mn->header->gen_params [i];
+               MonoGenericParam *gparam = &mn->gen_params [i];
 
                g_assert (gparam->pklass);
                gmethod->mtype_argv [i] = &gparam->pklass->byval_arg;
@@ -7440,6 +7582,7 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
        for (i = 0; i < dginst->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
                MonoClassField *field;
+               MonoInflatedField *ifield;
 
                if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
                        field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
@@ -7450,8 +7593,12 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                        g_assert_not_reached ();
                }
 
+               ifield = g_new0 (MonoInflatedField, 1);
+               ifield->generic_type = field->type;
+               ifield->reflection_info = obj;
+
                dginst->fields [i] = *field;
-               dginst->fields [i].generic_type = field->type;
+               dginst->fields [i].generic_info = ifield;
                dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
        }
 
@@ -7622,14 +7769,13 @@ typebuilder_setup_fields (MonoClass *klass)
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-                       field->def_value = g_new0 (MonoConstant, 1);
-                       idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+                       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->def_value->value = g_malloc (len);
-                       memcpy (field->def_value->value, p, len);
+                       field->data = g_malloc (len);
+                       memcpy (field->data, p, len);
                }
        }
        mono_class_layout_fields (klass);