[sre] Resolve EnumBuilder tokens in managed. (Fixes #58361)
authorAleksey Kliger <aleksey@xamarin.com>
Wed, 26 Jul 2017 20:59:22 +0000 (16:59 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Thu, 27 Jul 2017 15:41:29 +0000 (11:41 -0400)
In particular, delegate to the TypeBuilder within the EnumBuilder.

Also do not register the EnumBuilder object with the runtime.  (Fixes
https://bugzilla.xamarin.com/show_bug.cgi?id=58361)

mcs/class/corlib/System.Reflection.Emit/EnumBuilder.cs
mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs
mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs
mono/metadata/dynamic-image.c
mono/metadata/sre.c

index cba66c11840021f0404590a53fd2c5c2d81c6164..f92c5dd486ca5e5f089cad0f61a6b0bb3948ab64 100644 (file)
@@ -71,6 +71,9 @@ namespace System.Reflection.Emit {
                        return _tb.InternalResolve (); 
                }
 
+               internal override Type RuntimeResolve () {
+                       return _tb.RuntimeResolve ();
+               }
 
                public override Assembly Assembly {
                        get {
index bf879e8e942f79961b352b37de60b39592e47a5f..eea1d4adfe4f6f6c8e96139db1066208ff04ab54 100644 (file)
@@ -814,7 +814,7 @@ namespace System.Reflection.Emit {
                        make_room (6);
                        ll_emit (opcode);
                        int token = token_gen.GetToken (cls, opcode != OpCodes.Ldtoken);
-                       if (cls is TypeBuilderInstantiation || cls is SymbolType || cls is TypeBuilder || cls is GenericTypeParameterBuilder)
+                       if (cls is TypeBuilderInstantiation || cls is SymbolType || cls is TypeBuilder || cls is GenericTypeParameterBuilder || cls is EnumBuilder)
                                add_token_fixup (cls);
                        emit_int (token);
                }
index 2e985180ef549a1f9daac1d89129ded9b73a354b..57064be3027b126630d841b5bf1deae4bd0a9620 100644 (file)
@@ -752,6 +752,11 @@ namespace System.Reflection.Emit {
                                        token = typedef_tokengen --;
                                else
                                        token = typeref_tokengen --;
+                       } else if (member is EnumBuilder) {
+                               token = GetPseudoToken ((member as  EnumBuilder).GetTypeBuilder(), create_open_instance);
+                               dict[member] = token;
+                               // n.b. don't register with the runtime, the TypeBuilder already did it.
+                               return token;
                        } else if (member is ConstructorBuilder) {
                                if (member.Module == this && !(member as ConstructorBuilder).TypeBuilder.ContainsGenericParameters)
                                        token = methoddef_tokengen --;
@@ -780,7 +785,8 @@ namespace System.Reflection.Emit {
                }
 
                internal int GetToken (MemberInfo member, bool create_open_instance) {
-                       if (member is TypeBuilderInstantiation || member is FieldOnTypeBuilderInst || member is ConstructorOnTypeBuilderInst || member is MethodOnTypeBuilderInst || member is SymbolType || member is FieldBuilder || member is TypeBuilder || member is ConstructorBuilder || member is MethodBuilder || member is GenericTypeParameterBuilder)
+                       if (member is TypeBuilderInstantiation || member is FieldOnTypeBuilderInst || member is ConstructorOnTypeBuilderInst || member is MethodOnTypeBuilderInst || member is SymbolType || member is FieldBuilder || member is TypeBuilder || member is ConstructorBuilder || member is MethodBuilder || member is GenericTypeParameterBuilder ||
+                           member is EnumBuilder)
                                return GetPseudoToken (member, create_open_instance);
                        return getToken (this, member, create_open_instance);
                }
@@ -873,6 +879,8 @@ namespace System.Reflection.Emit {
                                        finished = (member as FieldBuilder).RuntimeResolve ();
                                } else if (member is TypeBuilder) {
                                        finished = (member as TypeBuilder).RuntimeResolve ();
+                               } else if (member is EnumBuilder) {
+                                       finished = (member as EnumBuilder).RuntimeResolve ();
                                } else if (member is ConstructorBuilder) {
                                        finished = (member as ConstructorBuilder).RuntimeResolve ();
                                } else if (member is MethodBuilder) {
index 063b8e5570d1e52747b5e40f7da15397eb219bca..85fd2708111b57412ebf56997d5a28e1e9a7609a 100644 (file)
@@ -198,6 +198,7 @@ mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, Mo
        MONO_REQ_GC_UNSAFE_MODE;
 
        g_assert (!MONO_HANDLE_IS_NULL (obj));
+       g_assert (strcmp (mono_handle_class (obj)->name, "EnumBuilder"));
        dynamic_image_lock (assembly);
        MonoObject *prev = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
        if (prev) {
index eda0cf400756e1bbb0283f4df6d054865a4aa768..649791e7beafcb4104a181e0c720a2509ea53d4b 100644 (file)
@@ -1193,11 +1193,6 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                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));
        } else {
                g_error ("requested token for %s\n", klass->name);
        }