Merge pull request #615 from nealef/master
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / CodeGenerator.cs
index 46937367073e950f29cac73435b93df17f547f9d..671c196163e08ad69c39a05bf664164bfdbc25ac 100644 (file)
@@ -28,6 +28,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#if !FULL_AOT_RUNTIME
 using System;
 using System.IO;
 using System.Collections;
@@ -41,6 +42,8 @@ namespace System.Runtime.Serialization.Formatters.Binary
        internal class CodeGenerator
        {
                // Code generation
+
+               static object monitor = new object ();
                
                static ModuleBuilder _module;
                
@@ -54,7 +57,14 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        _module = myAsmBuilder.DefineDynamicModule("__MetadataTypesModule", false);
                }
                
-               static public Type GenerateMetadataType (Type type, StreamingContext context)
+               static public Type GenerateMetadataType (Type type, StreamingContext context) {
+                       /* SRE is not thread safe */
+                       lock (monitor) {
+                               return GenerateMetadataTypeInternal (type, context);
+                       }
+               }
+
+               static public Type GenerateMetadataTypeInternal (Type type, StreamingContext context)
                {               
                        string name = type.Name + "__TypeMetadata";
                        string sufix = "";
@@ -105,8 +115,13 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                        // EMIT ow.WriteAssembly (writer, memberType.Assembly);
                                        gen.Emit (OpCodes.Ldarg_1);
                                        gen.Emit (OpCodes.Ldarg_2);
+#if NET_4_0
+                                       EmitLoadType (gen, memberType);
+                                       gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteTypeAssembly"), null);
+#else
                                        EmitLoadTypeAssembly (gen, memberType, field.Name);
                                        gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
+#endif
                                        gen.Emit (OpCodes.Pop);
                                }
                        }
@@ -253,7 +268,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                ig.Emit (OpCodes.Ldind_Ref);
                }
 
-               public static void EmitWriteTypeSpec (ILGenerator gen, Type type, string member)
+               static void EmitWriteTypeSpec (ILGenerator gen, Type type, string member)
                {
                        // WARNING Keep in sync with WriteTypeSpec
                        
@@ -282,8 +297,14 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                        // EMIT writer.Write ((int)ow.GetAssemblyId (type.Assembly));
                                        gen.Emit (OpCodes.Ldarg_2);
                                        gen.Emit (OpCodes.Ldarg_1);
+#if NET_4_0
+                                       EmitLoadType (gen, type);
+                                       gen.EmitCall (OpCodes.Callvirt, typeof(GetForwardedAttribute).GetMethod("GetAssemblyName"), null);
+                                       gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyNameId"), null);
+#else
                                        EmitLoadTypeAssembly (gen, type, member);
                                        gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null);
+#endif
                                        gen.Emit (OpCodes.Conv_I4);
                                        EmitWrite (gen, typeof(int));
                                        break;
@@ -308,6 +329,12 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        gen.EmitCall (OpCodes.Callvirt, typeof(Type).GetProperty("Assembly").GetGetMethod(), null);
                }
                
+               static void EmitLoadType (ILGenerator gen, Type type)
+               {
+                       gen.Emit (OpCodes.Ldtoken, type);
+                       gen.EmitCall (OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
+               }
+               
                static void EmitWrite (ILGenerator gen, Type type)
                {
                        gen.EmitCall (OpCodes.Callvirt, typeof(BinaryWriter).GetMethod("Write", new Type[] { type }), null);
@@ -392,3 +419,4 @@ namespace System.Runtime.Serialization.Formatters.Binary
        }
  }
  
+#endif