In Assembly:
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ModuleBuilder.cs
index 33016a7398a2212ed15187ec4097dfe82b375114..672be8b6b6129c6830d81650b440bb8dc32d7280 100644 (file)
@@ -42,12 +42,12 @@ using System.Resources;
 using System.Globalization;
 
 namespace System.Reflection.Emit {
-#if NET_2_0
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_ModuleBuilder))]
-#endif
        [ClassInterface (ClassInterfaceType.None)]
        public class ModuleBuilder : Module, _ModuleBuilder {
+
+#pragma warning disable 169, 414
                #region Sync with object-internals.h
                private UIntPtr dynamic_image; /* GC-tracked */
                private int num_types;
@@ -61,6 +61,8 @@ namespace System.Reflection.Emit {
                bool is_main;
                private MonoResource[] resources;
                #endregion
+#pragma warning restore 169, 414
+               
                private TypeBuilder global_type;
                private Type global_type_created;
                Hashtable name_cache;
@@ -74,6 +76,9 @@ namespace System.Reflection.Emit {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern void basic_init (ModuleBuilder ab);
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private static extern void set_wrappers_type (ModuleBuilder mb, Type ab);
+
                internal ModuleBuilder (AssemblyBuilder assb, string name, string fullyqname, bool emitSymbolInfo, bool transient) {
                        this.name = this.scopename = name;
                        this.fqname = fullyqname;
@@ -88,17 +93,31 @@ namespace System.Reflection.Emit {
                        basic_init (this);
 
                        CreateGlobalType ();
-                       
+
+                       if (assb.IsRun) {
+                               TypeBuilder tb = new TypeBuilder (this, TypeAttributes.Abstract, 0xFFFFFF); /*last valid token*/
+                               Type type = tb.CreateType ();
+                               set_wrappers_type (this, type);
+                       }
+
                        if (emitSymbolInfo) {
+#if NET_2_1 && !MONOTOUCH
+                               symbolWriter = new Mono.CompilerServices.SymbolWriter.SymbolWriterImpl (this);
+#else
                                Assembly asm = Assembly.LoadWithPartialName ("Mono.CompilerServices.SymbolWriter");
+                               if (asm == null)
+                                       throw new ExecutionEngineException ("The assembly for default symbol writer cannot be loaded");
+
                                Type t = asm.GetType ("Mono.CompilerServices.SymbolWriter.SymbolWriterImpl");
-                               if (t != null) {
-                                       symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this });
-                                       string fileName = fqname;
-                                       if (assemblyb.AssemblyDir != null)
-                                               fileName = Path.Combine (assemblyb.AssemblyDir, fileName);
-                                       symbolWriter.Initialize (IntPtr.Zero, fileName, true);
-                               }
+                               if (t == null)
+                                       throw new ExecutionEngineException ("The type that implements the default symbol writer interface cannot be found");
+
+                               symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this });
+#endif
+                               string fileName = fqname;
+                               if (assemblyb.AssemblyDir != null)
+                                       fileName = Path.Combine (assemblyb.AssemblyDir, fileName);
+                               symbolWriter.Initialize (IntPtr.Zero, fileName, true);
                        }
                }
 
@@ -127,13 +146,16 @@ namespace System.Reflection.Emit {
                        return fb;
                }
 
-               public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) {
+               public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes)
+               {
                        if (name == null)
                                throw new ArgumentNullException ("name");
                        if (global_type_created != null)
                                throw new InvalidOperationException ("global fields already created");
-                       if (global_type == null)
-                               global_type = new TypeBuilder (this, 0);
+                       if ((size <= 0) || (size > 0x3f0000))
+                               throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
+
+                       CreateGlobalType ();
 
                        string typeName = "$ArrayType$" + size;
                        Type datablobtype = GetType (typeName, false, false);
@@ -179,12 +201,7 @@ namespace System.Reflection.Emit {
                        return DefineGlobalMethod (name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               public
-#else
-               internal
-#endif
-               MethodBuilder DefineGlobalMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
+               public MethodBuilder DefineGlobalMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
                {
                        if (name == null)
                                throw new ArgumentNullException ("name");
@@ -192,8 +209,7 @@ namespace System.Reflection.Emit {
                                throw new ArgumentException ("global methods must be static");
                        if (global_type_created != null)
                                throw new InvalidOperationException ("global methods already created");
-                       if (global_type == null)
-                               global_type = new TypeBuilder (this, 0);
+                       CreateGlobalType ();
                        MethodBuilder mb = global_type.DefineMethod (name, attributes, callingConvention, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
 
                        addGlobalMethod (mb);
@@ -211,8 +227,7 @@ namespace System.Reflection.Emit {
                                throw new ArgumentException ("global methods must be static");
                        if (global_type_created != null)
                                throw new InvalidOperationException ("global methods already created");
-                       if (global_type == null)
-                               global_type = new TypeBuilder (this, 0);
+                       CreateGlobalType ();
                        MethodBuilder mb = global_type.DefinePInvokeMethod (name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
 
                        addGlobalMethod (mb);
@@ -248,23 +263,30 @@ namespace System.Reflection.Emit {
                        num_types ++;
                }
 
-               private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packsize, int typesize) {
-                       if (name_cache.Contains (name))
-                               throw new ArgumentException ("Duplicate type name within an assembly.");
-
-                       TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packsize, typesize, null);
+               private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) {
+                       TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packingSize, typesize, null);
                        AddType (res);
-                       name_cache.Add (name, res);
+                       
+                       try {
+                               name_cache.Add (name, res);
+                       } catch {
+                               throw new ArgumentException ("Duplicate type name within an assembly.");
+                       }
+                       
                        return res;
                }
 
-               internal void RegisterTypeName (TypeBuilder tb, string name) {
+               internal void RegisterTypeName (TypeBuilder tb, string name)
+               {
                        name_cache.Add (name, tb);
                }
+               
+               internal TypeBuilder GetRegisteredType (string name)
+               {
+                       return (TypeBuilder) name_cache [name];
+               }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces) {
                        return DefineType (name, attr, parent, interfaces, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
                }
@@ -277,8 +299,8 @@ namespace System.Reflection.Emit {
                        return DefineType (name, attr, parent, null, packsize, TypeBuilder.UnspecifiedTypeSize);
                }
 
-               public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packsize, int typesize) {
-                       return DefineType (name, attr, parent, null, packsize, typesize);
+               public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) {
+                       return DefineType (name, attr, parent, null, packingSize, typesize);
                }
 
                public MethodInfo GetArrayMethod( Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) {
@@ -296,16 +318,12 @@ namespace System.Reflection.Emit {
                        return eb;
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public override Type GetType( string className) {
                        return GetType (className, false, false);
                }
                
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public override Type GetType( string className, bool ignoreCase) {
                        return GetType (className, false, ignoreCase);
                }
@@ -354,10 +372,14 @@ namespace System.Reflection.Emit {
                        return null;
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif         
-               public override Type GetType (string className, bool throwOnError, bool ignoreCase) {
+               public override Type GetType (string className, bool throwOnError, bool ignoreCase)
+               {
+                       if (className == null)
+                               throw new ArgumentNullException ("className");
+                       if (className.Length == 0)
+                               throw new ArgumentException ("className");
+
                        int subt;
                        string orig = className;
                        string modifiers;
@@ -393,9 +415,8 @@ namespace System.Reflection.Emit {
                                throw new TypeLoadException (orig);
                        if (result != null && (modifiers != null)) {
                                Type mt = create_modified_type (result, modifiers);
-                               if (mt is TypeBuilder)
-                                       result = mt as TypeBuilder;
-                               else
+                               result = mt as TypeBuilder;
+                               if (result == null)
                                        return mt;
                        }
                        if (result != null && result.is_created)
@@ -430,9 +451,7 @@ namespace System.Reflection.Emit {
                        }
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
                        SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
                }
@@ -452,12 +471,17 @@ namespace System.Reflection.Emit {
                public override Type [] GetTypes ()
                {
                        if (types == null)
-                               return new TypeBuilder [0];
+                               return Type.EmptyTypes;
 
                        int n = num_types;
-                       TypeBuilder [] copy = new TypeBuilder [n];
+                       Type [] copy = new Type [n];
                        Array.Copy (types, copy, n);
 
+                       // MS replaces the typebuilders with their created types
+                       for (int i = 0; i < copy.Length; ++i)
+                               if (types [i].is_created)
+                                       copy [i] = types [i].CreateType ();
+
                        return copy;
                }
 
@@ -518,7 +542,6 @@ namespace System.Reflection.Emit {
                        throw new NotImplementedException ();
                }
 
-#if NET_2_0
                public void DefineManifestResource (string name, Stream stream, ResourceAttributes attribute) {
                        if (name == null)
                                throw new ArgumentNullException ("name");
@@ -543,7 +566,6 @@ namespace System.Reflection.Emit {
                        resources [p].attrs = attribute;
                        resources [p].stream = stream;
                }
-#endif
 
                [MonoTODO]
                public void SetSymCustomAttribute (string name, byte[] data)
@@ -575,9 +597,7 @@ namespace System.Reflection.Emit {
                        return GetMethodToken (GetArrayMethod (arrayClass, methodName, callingConvention, returnType, parameterTypes));
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public MethodToken GetConstructorToken (ConstructorInfo con)
                {
                        if (con == null)
@@ -625,7 +645,7 @@ namespace System.Reflection.Emit {
                        return new TypeToken (GetToken (type));
                }
 
-               public TypeToken GetTypeToken (string type)
+               public TypeToken GetTypeToken (string name)
                {
                        return GetTypeToken (GetType (name));
                }
@@ -660,6 +680,13 @@ namespace System.Reflection.Emit {
                        return getToken (this, helper);
                }
 
+               /*
+                * Register the token->obj mapping with the runtime so the Module.Resolve... 
+                * methods will work for obj.
+                */
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               internal extern void RegisterToken (object obj, int token);
+
                internal TokenGenerator GetTokenGenerator () {
                        if (token_gen == null)
                                token_gen = new ModuleBuilderTokenGenerator (this);
@@ -755,12 +782,18 @@ namespace System.Reflection.Emit {
 
                internal void CreateGlobalType () {
                        if (global_type == null)
-                               global_type = new TypeBuilder (this, 0);
+                               global_type = new TypeBuilder (this, 0, 1);
+               }
+
+               internal override Guid GetModuleVersionId ()
+               {
+                       return new Guid (guid);
                }
 
+               // Used by mcs, the symbol writer, and mdb through reflection
                internal static Guid Mono_GetGuid (ModuleBuilder mb)
                {
-                       return new Guid (mb.guid);
+                       return mb.GetModuleVersionId ();
                }
 
                void _ModuleBuilder.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)