[sre] Map fieldref tokens to MonoClassField*
[mono.git] / mono / metadata / sre.c
index fbde1f1cc0fd3e00e6281d61ab0b514512a03609..b899c830e7898d960ad8418a4afb49c70ef2b882 100644 (file)
@@ -1,6 +1,7 @@
-/*
- * sre.c: Routines for creating an image at runtime
- *   and related System.Reflection.Emit icalls
+/**
+ * \file
+ * Routines for creating an image at runtime
+ * and related System.Reflection.Emit icalls
  *   
  * 
  * Author:
@@ -42,12 +43,12 @@ static GENERATE_GET_CLASS_WITH_CACHE (module_builder, "System.Reflection.Emit",
 static char* string_to_utf8_image_raw (MonoImage *image, MonoString *s, MonoError *error);
 
 #ifndef DISABLE_REFLECTION_EMIT
-static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error);
 static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError  *error);
 static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb);
 static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
-static gboolean reflection_create_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_init_generic_class (MonoReflectionTypeBuilderHandle tb, MonoError *error);
+static gboolean reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error);
 
 
 static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
@@ -90,7 +91,7 @@ string_to_utf8_image_raw (MonoImage *image, MonoString *s_raw, MonoError *error)
        /* FIXME all callers to string_to_utf8_image_raw should use handles */
        HANDLE_FUNCTION_ENTER ();
        char* result = NULL;
-       mono_error_init (error);
+       error_init (error);
        MONO_HANDLE_DCL (MonoString, s);
        result = mono_string_to_utf8_image (image, s, error);
        HANDLE_FUNCTION_RETURN_VAL (result);
@@ -296,7 +297,7 @@ method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflect
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       mono_error_init (error);
+       error_init (error);
 
        MonoExceptionClause *clauses;
        MonoExceptionClause *clause;
@@ -373,6 +374,12 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
        mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
        mono_loader_unlock ();
 
+}
+#else
+//FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
 }
 #endif
 
@@ -454,7 +461,7 @@ mono_reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb,
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       mono_error_init (error);
+       error_init (error);
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
 
        rmb->ilgen = mb->ilgen;
@@ -501,7 +508,7 @@ mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, M
 
        const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
 
-       mono_error_init (error);
+       error_init (error);
 
        memset (rmb, 0, sizeof (ReflectionMethodBuilder));
 
@@ -518,7 +525,8 @@ mono_reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, M
        rmb->call_conv = mb->call_conv;
        rmb->code = NULL;
        rmb->type = mb->type;
-       rmb->name = mono_string_new (mono_domain_get (), name);
+       rmb->name = mono_string_new_checked (mono_domain_get (), name, error);
+       return_val_if_nok (error, FALSE);
        rmb->table_idx = &mb->table_idx;
        rmb->init_locals = mb->init_locals;
        rmb->skip_visibility = FALSE;
@@ -639,7 +647,7 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
 }
 
 
-static guint32
+guint32
 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
 {
        MONO_REQ_GC_NEUTRAL_MODE;
@@ -720,6 +728,14 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina
        return token;
 }
 
+#else /* DISABLE_REFLECTION_EMIT */
+
+guint32
+mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
+{
+       g_assert_not_reached ();
+       return -1;
+}
 #endif
 
 static gboolean
@@ -730,7 +746,7 @@ is_field_on_inst (MonoClassField *field)
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, MonoClassField *field)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
 {
        MonoType *type;
        guint32 token;
@@ -738,7 +754,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M
        g_assert (field);
        g_assert (field->parent);
 
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, MONO_HANDLE_RAW (f)));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
        if (token)
                return token;
 
@@ -751,7 +767,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M
        token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
                                                                                        mono_field_get_name (field),
                                                                                        mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
-       mono_g_hash_table_insert (assembly->handleref_managed, MONO_HANDLE_RAW (f), GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -848,7 +864,7 @@ mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHel
        MonoDynamicTable *table;
        guint32 *values;
 
-       mono_error_init (error);
+       error_init (error);
 
        table = &assembly->tables [MONO_TABLE_STANDALONESIG];
        idx = table->next_idx ++;
@@ -898,7 +914,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        MonoMethodSignature *sig = NULL;
        char *name = NULL;
 
-       mono_error_init (error);
+       error_init (error);
 
        MonoArrayHandle parameters = MONO_HANDLE_NEW_GET (MonoArray, m, parameters);
        guint32 nparams = mono_array_handle_length (parameters);
@@ -1012,7 +1028,7 @@ mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStri
        }
 
        token = MONO_TOKEN_STRING | idx;
-       mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str));
+       mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
 
 leave:
        HANDLE_FUNCTION_RETURN_VAL (token);
@@ -1066,7 +1082,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj
 {
        guint32 token = 0;
 
-       mono_error_init (error);
+       error_init (error);
 
        MonoClass *klass = mono_handle_class (obj);
        if (strcmp (klass->name, "MonoMethod") == 0 || strcmp (klass->name, "MonoCMethod") == 0) {
@@ -1082,7 +1098,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj
                g_error ("requested method token for %s\n", klass->name);
        }
 
-       mono_dynamic_image_register_token (assembly, token, obj);
+       mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
        return token;
 fail:
        g_assert (!mono_error_ok (error));
@@ -1105,25 +1121,35 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                         gboolean create_open_instance, gboolean register_token,
                         MonoError *error)
 {
+       HANDLE_FUNCTION_ENTER ();
        guint32 token = 0;
 
-       mono_error_init (error);
+       error_init (error);
 
        MonoClass *klass = mono_handle_class (obj);
+       MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
+       MONO_HANDLE_ASSIGN (register_obj, obj);
 
        /* Check for user defined reflection objects */
        /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
        if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
                mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
-               return 0;
+               goto leave;
        }
 
+       /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
+       int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
+
        if (strcmp (klass->name, "RuntimeType") == 0) {
                MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
-               return_val_if_nok (error, 0);
+               if (!is_ok (error))
+                       goto leave;
                MonoClass *mc = mono_class_from_mono_type (type);
                token = mono_metadata_token_from_dor (
                        mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
+               /* If it's a RuntimeType now, we could have registered a
+                * TypeBuilder for it before, so replacing is okay. */
+               how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                           strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
@@ -1142,6 +1168,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                                 * FIXME: do the equivalent for Fields.
                                 */
                                token = method->token;
+                               how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
                        } else {
                                /*
                                 * Each token should have a unique index, but the indexes are
@@ -1150,6 +1177,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                                 */
                                method_table_idx --;
                                token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+                               how_collide = MONO_DYN_IMAGE_TOK_NEW;
                        }
                } else {
                        token = mono_image_get_methodref_token (assembly, method, create_open_instance);
@@ -1162,31 +1190,32 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+                       how_collide = MONO_DYN_IMAGE_TOK_NEW;
                } else {
-                       token = mono_image_get_fieldref_token (assembly, obj, field);
+                       token = mono_image_get_fieldref_token (assembly, field);
                }
                /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
        } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
                MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
-               token = mono_image_get_array_token (assembly, m, error);
-               return_val_if_nok (error, 0);
+               guint32 array_token = mono_image_get_array_token (assembly, m, error);
+               if (!is_ok (error))
+                       goto leave;
+               token = array_token;
        } else if (strcmp (klass->name, "SignatureHelper") == 0) {
                MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
-               token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
-               return_val_if_nok (error, 0);
-       } else if (strcmp (klass->name, "EnumBuilder") == 0) {
-               MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref (assembly, type));
+               guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
+               if (!is_ok (error))
+                       goto leave;
+               token = sig_token;
        } else {
                g_error ("requested token for %s\n", klass->name);
        }
 
        if (register_token)
-               mono_dynamic_image_register_token (assembly, token, obj);
+               mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
 
-       return token;
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (token);
 }
 
 
@@ -1194,6 +1223,25 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
 
 #ifndef DISABLE_REFLECTION_EMIT
 
+static gboolean
+assemblybuilderaccess_can_refonlyload (guint32 access)
+{
+       return (access & 0x4) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_run (guint32 access)
+{
+       return (access & MonoAssemblyBuilderAccess_Run) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_save (guint32 access)
+{
+       return (access & MonoAssemblyBuilderAccess_Save) != 0;
+}
+
+
 /*
  * mono_reflection_dynimage_basic_init:
  * @assembly: an assembly builder object
@@ -1212,14 +1260,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
        if (assemblyb->dynamic_assembly)
                return;
 
-#if HAVE_BOEHM_GC
-       /* assembly->assembly.image might be GC allocated */
-       assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
-#else
        assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
-#endif
 
-       mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+       MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
        
        assembly->assembly.ref_count = 1;
        assembly->assembly.dynamic = TRUE;
@@ -1255,8 +1298,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
                        assembly->assembly.aname.revision = 0;
         }
 
-       assembly->run = assemblyb->access != 2;
-       assembly->save = assemblyb->access != 1;
+       assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
+       assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
+       assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
        assembly->domain = domain;
 
        char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
@@ -1280,7 +1324,7 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 
        register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
        
-       mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+       MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
        
        mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
 }
@@ -1303,7 +1347,7 @@ register_module (MonoDomain *domain, MonoReflectionModuleBuilderHandle res, Mono
 static gboolean
 image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        MonoDomain *domain = MONO_HANDLE_DOMAIN (moduleb);
        MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
        MonoReflectionAssemblyBuilderHandle ab = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
@@ -1351,7 +1395,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e
 static gboolean
 mono_image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        return image_module_basic_init (moduleb, error);
 }
 
@@ -1379,7 +1423,7 @@ MonoType*
 mono_type_array_get_and_resolve (MonoArrayHandle array, int idx, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER();
-       mono_error_init (error);
+       error_init (error);
        MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
        MONO_HANDLE_ARRAY_GETREF (t, array, idx);
        MonoType *result = mono_reflection_type_handle_mono_type (t, error);
@@ -1466,7 +1510,7 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionTypeHandle t, Mon
        static MonoMethod *method_get_underlying_system_type = NULL;
        HANDLE_FUNCTION_ENTER ();
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!method_get_underlying_system_type)
                method_get_underlying_system_type = mono_class_get_method_from_name (mono_defaults.systemtype_class, "get_UnderlyingSystemType", 0);
@@ -1487,7 +1531,7 @@ MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref_raw, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER ();
-       mono_error_init (error);
+       error_init (error);
        MONO_HANDLE_DCL (MonoReflectionType, ref);
        MonoType *result = mono_reflection_type_handle_mono_type (ref, error);
        HANDLE_FUNCTION_RETURN_VAL (result);
@@ -1519,7 +1563,7 @@ reflection_instance_handle_mono_type (MonoReflectionGenericClassHandle ref_gclas
        }
        MonoClass *gtd_klass = mono_class_from_mono_type (gtd);
        if (is_sre_type_builder (mono_handle_class (ref_gtd))) {
-               reflection_create_generic_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
+               reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_gtd), error);
                if (!is_ok (error)) {
                        goto leave;
                }
@@ -1539,7 +1583,7 @@ static MonoType*
 reflection_param_handle_mono_type (MonoReflectionGenericParamHandle ref_gparam, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER ();
-       mono_error_init (error);
+       error_init (error);
        MonoType *result = NULL;
 
 
@@ -1596,7 +1640,7 @@ static MonoType*
 mono_type_array_get_and_resolve_raw (MonoArray* array_raw, int idx, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER(); /* FIXME callers of mono_type_array_get_and_resolve_raw should use handles */
-       mono_error_init (error);
+       error_init (error);
        MONO_HANDLE_DCL (MonoArray, array);
        MonoType *result = mono_type_array_get_and_resolve (array, idx, error);
        HANDLE_FUNCTION_RETURN_VAL (result);
@@ -1606,7 +1650,7 @@ MonoType*
 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER ();
-       mono_error_init (error);
+       error_init (error);
 
        MonoType* result = NULL;
 
@@ -1640,10 +1684,18 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *
                        goto leave;
                g_assert (base);
                gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
-               if (rank == 0) //single dimentional array
-                       result = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
-               else
-                       result = &mono_bounded_array_class_get (mono_class_from_mono_type (base), rank, TRUE)->byval_arg;
+               MonoClass *eclass = mono_class_from_mono_type (base);
+               result = mono_image_new0 (eclass->image, MonoType, 1);
+               if (rank == 0)  {
+                       result->type = MONO_TYPE_SZARRAY;
+                       result->data.klass = eclass;
+               } else {
+                       MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
+                       result->type = MONO_TYPE_ARRAY;
+                       result->data.array = at;
+                       at->eklass = eclass;
+                       at->rank = rank;
+               }
                MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
        } else if (is_sre_byref (klass)) {
                MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
@@ -1694,7 +1746,7 @@ parameters_to_signature (MonoImage *image, MonoArrayHandle parameters, MonoError
        MonoMethodSignature *sig;
        int count, i;
 
-       mono_error_init (error);
+       error_init (error);
 
        count = MONO_HANDLE_IS_NULL (parameters) ? 0 : mono_array_handle_length (parameters);
 
@@ -1718,7 +1770,7 @@ static MonoMethodSignature*
 ctor_builder_to_signature (MonoImage *image, MonoReflectionCtorBuilderHandle ctor, MonoError *error) {
        MonoMethodSignature *sig;
 
-       mono_error_init (error);
+       error_init (error);
 
        sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET (MonoArray, ctor, parameters), error);
        return_val_if_nok (error, NULL);
@@ -1741,7 +1793,7 @@ static MonoMethodSignature*
 method_builder_to_signature (MonoImage *image, MonoReflectionMethodBuilderHandle method, MonoError *error) {
        MonoMethodSignature *sig;
 
-       mono_error_init (error);
+       error_init (error);
 
        sig = parameters_to_signature (image, MONO_HANDLE_NEW_GET(MonoArray, method, parameters), error);
        return_val_if_nok (error, NULL);
@@ -1766,7 +1818,7 @@ dynamic_method_to_signature (MonoReflectionDynamicMethodHandle method, MonoError
        HANDLE_FUNCTION_ENTER ();
        MonoMethodSignature *sig = NULL;
 
-       mono_error_init (error);
+       error_init (error);
 
        sig = parameters_to_signature (NULL, MONO_HANDLE_NEW_GET (MonoArray, method, parameters), error);
        if (!is_ok (error))
@@ -1791,7 +1843,7 @@ leave:
 static void
 get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        MonoClass *klass = mono_object_class (prop);
        if (strcmp (klass->name, "PropertyBuilder") == 0) {
                MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
@@ -1811,7 +1863,7 @@ get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type, MonoErro
 static void
 get_field_name_and_type (MonoObject *field, char **name, MonoType **type, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        MonoClass *klass = mono_object_class (field);
        if (strcmp (klass->name, "FieldBuilder") == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
@@ -1923,7 +1975,7 @@ encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuf
 {
        MonoTypeEnum simple_type;
        
-       mono_error_init (error);
+       error_init (error);
        if ((p-buffer) + 10 >= *buflen) {
                char *newbuf;
                *buflen *= 2;
@@ -2177,7 +2229,7 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char
 {
        int len;
 
-       mono_error_init (error);
+       error_init (error);
 
        /* Preallocate a large enough buffer */
        if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
@@ -2216,16 +2268,15 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char
 
 /**
  * mono_reflection_get_custom_attrs_blob:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * 
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
  * Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data.
  */
 MonoArray*
 mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
@@ -2238,17 +2289,16 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
 
 /**
  * mono_reflection_get_custom_attrs_blob_checked:
- * @ctor: custom attribute constructor
- * @ctorArgs: arguments o the constructor
- * @properties:
- * @propValues:
- * @fields:
- * @fieldValues:
- * @error: set on error
- * 
+ * \param ctor custom attribute constructor
+ * \param ctorArgs arguments o the constructor
+ * \param properties
+ * \param propValues
+ * \param fields
+ * \param fieldValues
+ * \param error set on error
  * Creates the blob of data that needs to be saved in the metadata and that represents
- * the custom attributed described by @ctor, @ctorArgs etc.
- * Returns: a Byte array representing the blob of data.  On failure returns NULL and sets @error.
+ * the custom attributed described by \p ctor, \p ctorArgs etc.
+ * \returns a \c Byte array representing the blob of data.  On failure returns NULL and sets \p error.
  */
 MonoArray*
 mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues, MonoError *error) 
@@ -2259,7 +2309,7 @@ mono_reflection_get_custom_attrs_blob_checked (MonoReflectionAssembly *assembly,
        char *buffer, *p;
        guint32 buflen, i;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
                /* sig is freed later so allocate it in the heap */
@@ -2336,52 +2386,65 @@ leave:
        return result;
 }
 
-/**
- * reflection_setup_internal_class:
- * @tb: a TypeBuilder object
- * @error: set on error
- *
- * Creates a MonoClass that represents the TypeBuilder.
- * This is a trick that lets us simplify a lot of reflection code
- * (and will allow us to support Build and Run assemblies easier).
- *
- * Returns TRUE on success. On failure, returns FALSE and sets @error.
- */
 static gboolean
-reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+reflection_setup_class_hierarchy (GHashTable *unparented, MonoError *error)
 {
-       HANDLE_FUNCTION_ENTER ();
-       mono_error_init (error);
+       error_init (error);
 
        mono_loader_lock ();
 
-       MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
-       MonoClass *parent = NULL;
-       if (!MONO_HANDLE_IS_NULL (ref_parent)) {
-               MonoType *parent_type = mono_reflection_type_handle_mono_type (ref_parent, error);
-               if (!is_ok (error))
-                       goto leave;
-               /* check so we can compile corlib correctly */
-               if (strcmp (mono_handle_class (ref_parent)->name, "TypeBuilder") == 0) {
-                       /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
-                       parent = parent_type->data.klass;
-               } else {
-                       parent = mono_class_from_mono_type (parent_type);
+       MonoType *parent_type;
+       MonoType *child_type;
+       GHashTableIter iter;
+
+       g_hash_table_iter_init (&iter, unparented);
+
+       while (g_hash_table_iter_next (&iter, (gpointer *) &child_type, (gpointer *) &parent_type)) {
+               MonoClass *child_class = mono_class_from_mono_type (child_type);
+               if (parent_type != NULL) {
+                       MonoClass *parent_class = mono_class_from_mono_type (parent_type);
+                       child_class->parent = NULL;
+                       /* fool mono_class_setup_parent */
+                       child_class->supertypes = NULL;
+                       mono_class_setup_parent (child_class, parent_class);
+               } else if (strcmp (child_class->name, "Object") == 0 && strcmp (child_class->name_space, "System") == 0) {
+                       const char *old_n = child_class->name;
+                       /* trick to get relative numbering right when compiling corlib */
+                       child_class->name = "BuildingObject";
+                       mono_class_setup_parent (child_class, mono_defaults.object_class);
+                       child_class->name = old_n;
                }
+               mono_class_setup_mono_type (child_class);
+               mono_class_setup_supertypes (child_class);
        }
-       
-       /* the type has already being created: it means we just have to change the parent */
-       MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
-       if (type != NULL) {
-               MonoClass *klass = mono_class_from_mono_type (type);
-               klass->parent = NULL;
-               /* fool mono_class_setup_parent */
-               klass->supertypes = NULL;
-               mono_class_setup_parent (klass, parent);
-               mono_class_setup_mono_type (klass);
+
+       mono_loader_unlock ();
+       return is_ok (error);
+}
+
+static gboolean
+reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       error_init (error);
+
+       mono_loader_lock ();
+
+       gint32 entering_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_tb), state);
+       if (entering_state != MonoTypeBuilderNew) {
+               g_assert (MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type));
                goto leave;
        }
 
+       MONO_HANDLE_SETVAL (ref_tb, state, MonoTypeBuilderState, MonoTypeBuilderEntered);
+       MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+       GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+       // If this type is already setup, exit. We'll fix the parenting later
+       MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
+       if (type)
+               goto leave;
+
        MonoReflectionModuleBuilderHandle ref_module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
        MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (ref_module, dynamic_image);
 
@@ -2409,7 +2472,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr
        klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
        mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
        
-       mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
+       MONO_PROFILER_RAISE (class_loading, (klass));
 
        klass->element_class = klass;
 
@@ -2430,17 +2493,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr
        */
        mono_image_append_class_to_reflection_info_set (klass);
 
-       mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb));
-
-       if (parent != NULL) {
-               mono_class_setup_parent (klass, parent);
-       } else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
-               const char *old_n = klass->name;
-               /* trick to get relative numbering right when compiling corlib */
-               klass->name = "BuildingObject";
-               mono_class_setup_parent (klass, mono_defaults.object_class);
-               klass->name = old_n;
-       }
+       mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
 
        if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
                        (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
@@ -2452,14 +2505,52 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr
 
        mono_class_setup_mono_type (klass);
 
-       mono_class_setup_supertypes (klass);
-
        /*
         * FIXME: handle interfaces.
         */
-
        MonoReflectionTypeHandle ref_tb_type = MONO_HANDLE_CAST (MonoReflectionType, ref_tb);
        MONO_HANDLE_SETVAL (ref_tb_type, type, MonoType*, &klass->byval_arg);
+       MONO_HANDLE_SETVAL (ref_tb, state, gint32, MonoTypeBuilderFinished);
+
+       reflection_init_generic_class (ref_tb, error);
+       if (!is_ok (error))
+               goto leave;
+
+       // Do here so that the search inside of the parent can see the above type that's been set.
+       MonoReflectionTypeHandle ref_parent = MONO_HANDLE_NEW_GET (MonoReflectionType, ref_tb, parent);
+       MonoType *parent_type = NULL;
+       if (!MONO_HANDLE_IS_NULL (ref_parent)) {
+               MonoClass *parent_klass = mono_handle_class (ref_parent);
+               gboolean recursive_init = TRUE;
+
+               if (is_sre_type_builder (parent_klass)) {
+                       MonoTypeBuilderState parent_state = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_parent), state);
+
+                       if (parent_state != MonoTypeBuilderNew) {
+                               // Initialize types reachable from parent recursively
+                               // We'll fix the type hierarchy later
+                               recursive_init = FALSE;
+                       }
+               }
+
+               if (recursive_init) {
+                       // If we haven't encountered a cycle, force the creation of ref_parent's type
+                       mono_reflection_type_handle_mono_type (ref_parent, error);
+                       if (!is_ok (error))
+                               goto leave;
+               }
+
+               parent_type = MONO_HANDLE_GETVAL (ref_parent, type);
+
+               // If we failed to create the parent, fail the child
+               if (!parent_type)
+                       goto leave;
+       }
+
+       // Push the child type and parent type to process later
+       // Note: parent_type may be null.
+       g_assert (!g_hash_table_lookup (unparented_classes, &klass->byval_arg));
+       g_hash_table_insert (unparented_classes, &klass->byval_arg, parent_type);
 
        if (!MONO_HANDLE_IS_NULL (ref_nesting_type)) {
                if (!reflection_setup_internal_class (MONO_HANDLE_CAST (MonoReflectionTypeBuilder, ref_nesting_type), error))
@@ -2473,7 +2564,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr
 
        /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
 
-       mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+       MONO_PROFILER_RAISE (class_loaded, (klass));
        
 leave:
        mono_loader_unlock ();
@@ -2481,23 +2572,25 @@ leave:
 }
 
 /**
- * reflection_create_generic_class:
+ * reflection_init_generic_class:
  * @tb: a TypeBuilder object
  * @error: set on error
  *
  * Creates the generic class after all generic parameters have been added.
  * On success returns TRUE, on failure returns FALSE and sets @error.
+ *
+ * This assumes that reflection_setup_internal_class has already set up
+ * ref_tb
  */
 static gboolean
-reflection_create_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+reflection_init_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER ();
 
-       mono_error_init (error);
+       error_init (error);
 
-       reflection_setup_internal_class (ref_tb, error);
-       if (!is_ok (error))
-               goto leave;
+       MonoTypeBuilderState ref_state = MONO_HANDLE_GETVAL (ref_tb, state);
+       g_assert (ref_state == MonoTypeBuilderFinished);
 
        MonoType *type = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionType, ref_tb), type);
        MonoClass *klass = mono_class_from_mono_type (type);
@@ -2538,6 +2631,11 @@ reflection_create_generic_class (MonoReflectionTypeBuilderHandle ref_tb, MonoErr
        }
 
        generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container);
+       MonoGenericContext* context = &generic_container->context;
+       MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst;
+       canonical_inst->type = MONO_TYPE_GENERICINST;
+       canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE);
+
 leave:
        HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
 }
@@ -2548,7 +2646,7 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
 {
        MonoMarshalSpec *res;
 
-       mono_error_init (error);
+       error_init (error);
 
        res = image_g_new0 (image, MonoMarshalSpec, 1);
        res->native = (MonoMarshalNative)minfo->type;
@@ -2604,7 +2702,7 @@ MonoReflectionMarshalAsAttributeHandle
 mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
                                                        MonoMarshalSpec *spec, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        
        MonoReflectionMarshalAsAttributeHandle minfo = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, mono_object_new_checked (domain, mono_class_get_marshal_as_attribute_class (), error));
        if (!is_ok (error))
@@ -2676,7 +2774,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        gboolean dynamic;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
        /*
         * Methods created using a MethodBuilder should have their memory allocated
         * inside the image mempool, while dynamic methods should have their memory
@@ -2694,7 +2792,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
        else
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
 
        wrapperm = (MonoMethodWrapper*)m;
 
@@ -2789,6 +2887,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                }
 
                wrapperm->header = header;
+               MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
+               dm->assembly = klass->image->assembly;
        }
 
        if (rmb->generic_params) {
@@ -2976,7 +3076,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilderHandl
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
 
-       mono_error_init (error);
+       error_init (error);
 
        mono_loader_lock ();
 
@@ -3004,7 +3104,7 @@ static MonoMethod*
 methodbuilder_to_mono_method_raw (MonoClass *klass, MonoReflectionMethodBuilder* mb_raw, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER (); /* FIXME change callers of methodbuilder_to_mono_method_raw to use handles */
-       mono_error_init (error);
+       error_init (error);
        MONO_HANDLE_DCL (MonoReflectionMethodBuilder, mb);
        MonoMethod *result = methodbuilder_to_mono_method (klass, mb, error);
        HANDLE_FUNCTION_RETURN_VAL (result);
@@ -3032,7 +3132,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
        MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (klass->wastypebuilder)
                return TRUE;
@@ -3121,7 +3221,7 @@ ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
 {
        MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!ensure_runtime_vtable (gklass, error))
                return FALSE;
@@ -3143,7 +3243,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
        MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
        int i, num, j;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
                return TRUE;
@@ -3222,7 +3322,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
 static MonoMethod*
 mono_reflection_method_get_handle (MonoObject *method, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        MonoClass *klass = mono_object_class (method);
        if (is_sr_mono_method (klass)) {
                MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
@@ -3252,7 +3352,7 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
        int i, j, onum;
        MonoReflectionMethod *m;
 
-       mono_error_init (error);
+       error_init (error);
        *overrides = NULL;
        *num_overrides = 0;
 
@@ -3324,7 +3424,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        int fcount = tb->num_fields;
        mono_class_set_field_count (klass, fcount);
 
-       mono_error_init (error);
+       error_init (error);
 
        if (tb->class_size) {
                packing_size = tb->packing_size;
@@ -3361,6 +3461,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                        return_if_nok (error);
                }
 
+               if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
+                       mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
+                       continue;
+               }
+
                if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
                        char *base = mono_array_addr (rva_data, char, 0);
                        size_t size = mono_array_length (rva_data);
@@ -3386,7 +3491,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                }
        }
 
-       mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+       if (!mono_class_has_failure (klass)) {
+               mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
+       }
 }
 
 static void
@@ -3399,7 +3506,7 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error)
        MonoClassPropertyInfo *info;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
 
        info = mono_class_get_property_info (klass);
        if (!info) {
@@ -3453,7 +3560,7 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error)
        MonoClassEventInfo *info;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
 
        info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo));
        mono_class_set_event_info (klass, info);
@@ -3526,12 +3633,51 @@ remove_instantiations_of_and_ensure_contents (gpointer key,
                return FALSE;
 }
 
+/**
+ * reflection_setup_internal_class:
+ * @tb: a TypeBuilder object
+ * @error: set on error
+ *
+ * Creates a MonoClass that represents the TypeBuilder.
+ * This is a trick that lets us simplify a lot of reflection code
+ * (and will allow us to support Build and Run assemblies easier).
+ *
+ * Returns TRUE on success. On failure, returns FALSE and sets @error.
+ */
+static gboolean
+reflection_setup_internal_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
+{
+       MonoReflectionModuleBuilderHandle module_ref = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, ref_tb, module);
+       GHashTable *unparented_classes = MONO_HANDLE_GETVAL(module_ref, unparented_classes);
+
+       if (unparented_classes) {
+               return reflection_setup_internal_class_internal (ref_tb, error);
+       } else {
+               // If we're not being called recursively
+               unparented_classes = g_hash_table_new (NULL, NULL);
+               MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, unparented_classes);
+
+               gboolean ret_val = reflection_setup_internal_class_internal (ref_tb, error);
+               mono_error_assert_ok (error);
+
+               // Fix the relationship between the created classes and their parents
+               reflection_setup_class_hierarchy (unparented_classes, error);
+               mono_error_assert_ok (error);
+
+               g_hash_table_destroy (unparented_classes);
+               MONO_HANDLE_SETVAL (module_ref, unparented_classes, GHashTable *, NULL);
+
+               return ret_val;
+       }
+}
+
+
 MonoReflectionTypeHandle
 ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_tb, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 
-       reflection_create_generic_class (ref_tb, error);
+       reflection_setup_internal_class (ref_tb, error);
        mono_error_assert_ok (error);
 
        MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_tb);
@@ -3704,7 +3850,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono
        GSList *l;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (mono_runtime_is_shutting_down ()) {
                mono_error_set_generic_error (error, "System", "InvalidOperationException", "");
@@ -3779,6 +3925,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono
                rmb.refs [i + 1] = handle_class;
        }               
 
+       MonoAssembly *ass = NULL;
        if (mb->owner) {
                MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
                if (!is_ok (error)) {
@@ -3786,11 +3933,14 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono
                        return FALSE;
                }
                klass = mono_class_from_mono_type (owner_type);
+               ass = klass->image->assembly;
        } else {
                klass = mono_defaults.object_class;
+               ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
        }
 
        mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+       ((MonoDynamicMethod*)handle)->assembly = ass;
        g_free (rmb.refs);
        return_val_if_nok (error, FALSE);
 
@@ -3843,7 +3993,7 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32
        MonoMethodSignature *sig;
        g_assert (image_is_dynamic (image));
 
-       mono_error_init (error);
+       error_init (error);
 
        sig = (MonoMethodSignature *)g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
        if (sig)
@@ -3863,7 +4013,7 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32
 static void
 ensure_complete_type (MonoClass *klass, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 
        if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info_raw (klass); /* FIXME use handles */
@@ -3892,7 +4042,7 @@ mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **h
        MonoClass *oklass = obj->vtable->klass;
        gpointer result = NULL;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (strcmp (oklass->name, "String") == 0) {
                result = mono_string_intern_checked ((MonoString*)obj, error);
@@ -4120,7 +4270,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
 void
 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        *overrides = NULL;
        *num_overrides = 0;
 }
@@ -4135,13 +4285,13 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle tb,
 void 
 ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethodHandle mb, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 }
 
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        if (!ref)
                return NULL;
        return ref->type;
@@ -4150,7 +4300,7 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error)
 MonoType*
 mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        if (MONO_HANDLE_IS_NULL (ref))
                return NULL;
        return MONO_HANDLE_GETVAL (ref, type);
@@ -4162,14 +4312,14 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *
 void
 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
 {
-       mono_gc_deregister_root ((char*) &entry->gparam);
+       MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
        g_free (entry);
 }
 
 gint32
 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, gboolean create_open_instance, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        if (MONO_HANDLE_IS_NULL (obj)) {
                mono_error_set_argument_null (error, "obj", "");
                return 0;
@@ -4183,7 +4333,7 @@ ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilderHandle mb,
                                        MonoArrayHandle opt_param_types,
                                        MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        if (MONO_HANDLE_IS_NULL (method)) {
                mono_error_set_argument_null (error, "method", "");
                return 0;
@@ -4211,20 +4361,18 @@ ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
 void
 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
 {
-       mono_error_init (error);
-       mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj);
+       error_init (error);
+       /* This function may be called by ModuleBuilder.FixupTokens to update
+        * an existing token, so replace is okay here. */
+       mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
 }
 
-MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+MonoObjectHandle
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
 {
-       MonoObject *obj;
-
-       mono_loader_lock ();
-       obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
-       mono_loader_unlock ();
-
-       return obj;
+       error_init (error);
+       MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+       return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -4245,16 +4393,30 @@ ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 }
 
 void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
-                                                                          MonoReflectionType *t)
+ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
 {
-       enumtype->type = t->type;
+       MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
+
+       MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
+       g_assert (assembly);
+
+       mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
+}
+
+void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
+                                      MonoReflectionTypeHandle t,
+                                      MonoError *error)
+{
+       error_init (error);
+       MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
 }
 
 void
 ves_icall_ModuleBuilder_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        mono_image_module_basic_init (moduleb, error);
 }
 
@@ -4265,10 +4427,12 @@ ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, Mo
 }
 
 void
-ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
 {
-       MonoDynamicImage *image = moduleb->dynamic_image;
+       error_init (error);
+       MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
+       MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
 
-       g_assert (type->type);
-       image->wrappers_type = mono_class_from_mono_type (type->type);
+       g_assert (type);
+       image->wrappers_type = mono_class_from_mono_type (type);
 }