2004-07-12 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / reflection.c
index 7691e4e21d3536e8ad86044883c87c54b6946bfa..3238759cad6d046d8527745af7f117bfb758bc27 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>
@@ -135,6 +138,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);
@@ -1051,7 +1055,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)
@@ -1071,20 +1075,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);
                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");
@@ -1123,16 +1127,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 ();
@@ -1202,18 +1206,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;
+                               }
                        }
                }
        }
@@ -1353,14 +1368,14 @@ 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);
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
                tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method);
                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 ();
@@ -1406,7 +1421,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] ? ta->aname.public_key_token : "null");
        g_free (name);
        return result;
 }
@@ -1687,7 +1702,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;
@@ -1713,7 +1728,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);
        }
 }
@@ -1798,14 +1813,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;
        }
 }
 
@@ -1850,21 +1865,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;
        }
 }
 
@@ -1906,20 +1921,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");
@@ -2027,8 +2042,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;
@@ -2070,8 +2085,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;
 }
@@ -2119,7 +2134,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;
@@ -2152,7 +2167,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;
        }
@@ -2160,8 +2175,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);
        }
@@ -2173,7 +2188,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);
@@ -2195,29 +2210,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;
        }
@@ -2340,7 +2355,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++)
@@ -2378,10 +2393,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 ();
@@ -2477,7 +2492,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;
@@ -2502,17 +2517,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;
        }
@@ -2866,7 +2881,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);
        }
 }
 
@@ -2874,33 +2889,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);
                }
        }
@@ -2909,7 +2924,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);
                }
        }
@@ -2924,7 +2939,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)
@@ -3010,9 +3025,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);
 
@@ -3120,6 +3135,16 @@ compare_nested (const void *a, const void *b)
        return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
 }
 
+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;
+       }
+}
+
 /*
  * 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 
@@ -3165,7 +3190,13 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        /* 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;
@@ -3190,6 +3221,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;
@@ -3444,8 +3478,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);
@@ -3453,7 +3487,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;
                        }
                }
        }
@@ -3509,7 +3543,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);
@@ -3659,7 +3693,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));
                                }
                        }
                }
@@ -3762,7 +3796,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);
 
@@ -3858,11 +3892,11 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
                }
 
                parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
-               g_assert ((parent & TYPEDEFORREF_MASK) == MEMBERREF_PARENT_TYPEREF);
-               parent >>= TYPEDEFORREF_BITS;
+               g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
+               parent >>= MONO_TYPEDEFORREF_BITS;
 
-               parent <<= MEMBERREF_PARENT_BITS;
-               parent |= MEMBERREF_PARENT_TYPEREF;
+               parent <<= MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_TYPEREF;
 
                sig_token = method_encode_signature (assembly, sig);
                token = mono_image_get_varargs_method_token (
@@ -3880,8 +3914,8 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
                parent = mono_image_create_token (assembly, obj);
                g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
 
-               parent = mono_metadata_token_index (parent) << MEMBERREF_PARENT_BITS;
-               parent |= MEMBERREF_PARENT_METHODDEF;
+               parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_METHODDEF;
 
                token = mono_image_get_varargs_method_token (
                        assembly, parent, mono_string_to_utf8 (rmb.name), sig);
@@ -4555,23 +4589,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);
        }    
@@ -4843,7 +4879,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;
@@ -4926,7 +4962,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);
@@ -5081,7 +5117,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);
@@ -5154,7 +5190,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;
@@ -5267,7 +5306,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++;
@@ -5315,10 +5354,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 != ',')
@@ -5550,7 +5594,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);
@@ -5627,15 +5671,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;
        }
@@ -5987,11 +6033,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);
@@ -6000,9 +6046,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];
@@ -6069,12 +6115,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:
@@ -6102,8 +6148,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);
 }
 
@@ -6116,8 +6162,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);
 }
 
@@ -6130,8 +6176,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);
 }
 
@@ -6144,8 +6190,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);
 }
 
@@ -6158,8 +6204,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);
 }
 
@@ -6172,8 +6218,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);
 }
 
@@ -6186,8 +6232,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);
 }
 
@@ -6213,7 +6259,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;
        }
 
@@ -6236,8 +6282,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);
 }
 
@@ -6389,10 +6435,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) {
@@ -6402,7 +6459,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) {
@@ -6491,7 +6549,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;
@@ -6505,8 +6563,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;
        }
@@ -6592,7 +6660,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)
@@ -6653,7 +6721,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);
                }
        }
@@ -6690,12 +6758,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);
                }
        }
@@ -6726,10 +6796,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) {
@@ -6740,6 +6806,21 @@ 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);
+               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);
@@ -7128,14 +7209,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;
@@ -7630,14 +7710,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);