Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ModuleBuilder.cs
index a56d7004e18e6411dbf5cf50a03734c778e7dd11..32aa0b81fbe407e3c628485bfef489947820f426 100644 (file)
@@ -1,4 +1,3 @@
-
 //
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
 //
 
+#if !FULL_AOT_RUNTIME
 using System;
 using System.Reflection;
 using System.Collections;
+using System.Collections.Generic;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Diagnostics.SymbolStore;
@@ -42,11 +43,10 @@ using System.Resources;
 using System.Globalization;
 
 namespace System.Reflection.Emit {
-#if NET_2_0
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_ModuleBuilder))]
-#endif
        [ClassInterface (ClassInterfaceType.None)]
+       [StructLayout (LayoutKind.Sequential)]
        public class ModuleBuilder : Module, _ModuleBuilder {
 
 #pragma warning disable 169, 414
@@ -68,7 +68,7 @@ namespace System.Reflection.Emit {
                private TypeBuilder global_type;
                private Type global_type_created;
                Hashtable name_cache;
-               Hashtable us_string_cache = new Hashtable ();
+               Dictionary<string, int> us_string_cache;
                private int[] table_indexes;
                bool transient;
                ModuleBuilderTokenGenerator token_gen;
@@ -78,6 +78,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,20 +91,24 @@ namespace System.Reflection.Emit {
                        // guid = Guid.NewGuid().ToByteArray ();
                        table_idx = get_next_table_index (this, 0x00, true);
                        name_cache = new Hashtable ();
+                       us_string_cache = new Dictionary<string, int> (512);
 
                        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) {
                                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)
-                                       throw new ExecutionEngineException ("The type that implements the default symbol writer interface cannot be found");
+                                       throw new TypeLoadException ("The assembly for default symbol writer cannot be loaded");
 
+                               Type t = asm.GetType ("Mono.CompilerServices.SymbolWriter.SymbolWriterImpl", true);
                                symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this });
                                string fileName = fqname;
                                if (assemblyb.AssemblyDir != null)
@@ -144,8 +151,7 @@ namespace System.Reflection.Emit {
                        if ((size <= 0) || (size > 0x3f0000))
                                throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
 
-                       if (global_type == null)
-                               global_type = new TypeBuilder (this, 0);
+                       CreateGlobalType ();
 
                        string typeName = "$ArrayType$" + size;
                        Type datablobtype = GetType (typeName, false, false);
@@ -191,12 +197,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");
@@ -204,8 +205,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);
@@ -223,8 +223,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);
@@ -261,14 +260,14 @@ namespace System.Reflection.Emit {
                }
 
                private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) {
+                       if (name == null)
+                               throw new ArgumentNullException ("fullname");
+                       if (name_cache.ContainsKey (name))
+                               throw new ArgumentException ("Duplicate type name within an assembly.");
                        TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packingSize, typesize, null);
                        AddType (res);
-                       
-                       try {
-                               name_cache.Add (name, res);
-                       } catch {
-                               throw new ArgumentException ("Duplicate type name within an assembly.");
-                       }
+
+                       name_cache.Add (name, res);
                        
                        return res;
                }
@@ -283,9 +282,7 @@ namespace System.Reflection.Emit {
                        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);
                }
@@ -317,16 +314,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);
                }
@@ -375,10 +368,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;
@@ -450,9 +447,7 @@ namespace System.Reflection.Emit {
                        }
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
                        SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
                }
@@ -538,12 +533,11 @@ namespace System.Reflection.Emit {
                        if (resourceFileName == String.Empty)
                                throw new ArgumentException ("resourceFileName");
                        if (!File.Exists (resourceFileName) || Directory.Exists (resourceFileName))
-                               throw new FileNotFoundException ("File '" + resourceFileName + "' does not exists or is a directory.");
+                               throw new FileNotFoundException ("File '" + resourceFileName + "' does not exist or is a directory.");
 
                        throw new NotImplementedException ();
                }
 
-#if NET_2_0
                public void DefineManifestResource (string name, Stream stream, ResourceAttributes attribute) {
                        if (name == null)
                                throw new ArgumentNullException ("name");
@@ -568,7 +562,6 @@ namespace System.Reflection.Emit {
                        resources [p].attrs = attribute;
                        resources [p].stream = stream;
                }
-#endif
 
                [MonoTODO]
                public void SetSymCustomAttribute (string name, byte[] data)
@@ -600,13 +593,13 @@ 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)
                                throw new ArgumentNullException ("con");
+                       if (con.DeclaringType.Module != this)
+                               throw new InvalidOperationException ("The constructor is not in this module");
                        return new MethodToken (GetToken (con));
                }
 
@@ -659,30 +652,37 @@ namespace System.Reflection.Emit {
                private static extern int getUSIndex (ModuleBuilder mb, string str);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern int getToken (ModuleBuilder mb, object obj);
+               private static extern int getToken (ModuleBuilder mb, object obj, bool create_open_instance);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern int getMethodToken (ModuleBuilder mb, MethodInfo method,
+               private static extern int getMethodToken (ModuleBuilder mb, MethodBase method,
                                                          Type[] opt_param_types);
 
-               internal int GetToken (string str) {
-                       if (us_string_cache.Contains (str))
-                               return (int)us_string_cache [str];
-                       int result = getUSIndex (this, str);
-                       us_string_cache [str] = result;
+               internal int GetToken (string str)
+               {
+                       int result;
+                       if (!us_string_cache.TryGetValue (str, out result)) {
+                               result = getUSIndex (this, str);
+                               us_string_cache [str] = result;
+                       }
+                       
                        return result;
                }
 
                internal int GetToken (MemberInfo member) {
-                       return getToken (this, member);
+                       return getToken (this, member, true);
+               }
+
+               internal int GetToken (MemberInfo member, bool create_open_instance) {
+                       return getToken (this, member, create_open_instance);
                }
 
-               internal int GetToken (MethodInfo method, Type[] opt_param_types) {
+               internal int GetToken (MethodBase method, Type[] opt_param_types) {
                        return getMethodToken (this, method, opt_param_types);
                }
 
                internal int GetToken (SignatureHelper helper) {
-                       return getToken (this, helper);
+                       return getToken (this, helper, true);
                }
 
                /*
@@ -787,7 +787,7 @@ 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 ()
@@ -820,6 +820,148 @@ namespace System.Reflection.Emit {
                {
                        throw new NotImplementedException ();
                }
+
+#if NET_4_0
+               public override Assembly Assembly {
+                       get { return assemblyb; }
+               }
+
+               public override string Name {
+                       get { return name; }
+               }
+
+               public override string ScopeName {
+                       get { return name; }
+               }
+
+               public override Guid ModuleVersionId {
+                       get {
+                               return GetModuleVersionId ();
+                       }
+               }
+
+               //XXX resource modules can't be defined with ModuleBuilder
+               public override bool IsResource ()
+               {
+                       return false;
+               }
+
+               protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
+               {
+                       if (global_type_created == null)
+                               return null;
+                       if (types == null)
+                               return global_type_created.GetMethod (name);
+                       return global_type_created.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers);
+               }
+
+               public override FieldInfo ResolveField (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
+                       ResolveTokenError error;
+
+                       IntPtr handle = ResolveFieldToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+                       if (handle == IntPtr.Zero)
+                               throw resolve_token_exception (metadataToken, error, "Field");
+                       else
+                               return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
+               }
+
+               public override MemberInfo ResolveMember (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
+
+                       ResolveTokenError error;
+
+                       MemberInfo m = ResolveMemberToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+                       if (m == null)
+                               throw resolve_token_exception (metadataToken, error, "MemberInfo");
+                       else
+                               return m;
+               }
+
+               public override MethodBase ResolveMethod (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
+                       ResolveTokenError error;
+
+                       IntPtr handle = ResolveMethodToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+                       if (handle == IntPtr.Zero)
+                               throw resolve_token_exception (metadataToken, error, "MethodBase");
+                       else
+                               return MethodBase.GetMethodFromHandleNoGenericCheck (new RuntimeMethodHandle (handle));
+               }
+
+               public override string ResolveString (int metadataToken) {
+                       ResolveTokenError error;
+
+                       string s = ResolveStringToken (_impl, metadataToken, out error);
+                       if (s == null)
+                               throw resolve_token_exception (metadataToken, error, "string");
+                       else
+                               return s;
+               }
+
+               public override byte[] ResolveSignature (int metadataToken) {
+                       ResolveTokenError error;
+
+                   byte[] res = ResolveSignature (_impl, metadataToken, out error);
+                       if (res == null)
+                               throw resolve_token_exception (metadataToken, error, "signature");
+                       else
+                               return res;
+               }
+
+               public override Type ResolveType (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
+                       ResolveTokenError error;
+
+                       IntPtr handle = ResolveTypeToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+                       if (handle == IntPtr.Zero)
+                               throw resolve_token_exception (metadataToken, error, "Type");
+                       else
+                               return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
+               }
+
+               public override bool Equals (object obj)
+               {
+                       return base.Equals (obj);
+               }
+
+               public override int GetHashCode ()
+               {
+                       return base.GetHashCode ();
+               }
+
+               public override bool IsDefined (Type attributeType, bool inherit)
+               {
+                       return base.IsDefined (attributeType, inherit);
+               }
+
+               public override object[] GetCustomAttributes (bool inherit)
+               {
+                       return base.GetCustomAttributes (inherit);
+               }
+
+               public override object[] GetCustomAttributes (Type attributeType, bool inherit)
+               {
+                       return base.GetCustomAttributes (attributeType, inherit);
+               }
+
+               public override FieldInfo GetField (string name, BindingFlags bindingAttr)
+               {
+                       return base.GetField (name, bindingAttr);
+               }
+
+               public override FieldInfo[] GetFields (BindingFlags bindingFlags)
+               {
+                       return base.GetFields (bindingFlags);
+               }
+
+               public override MethodInfo[] GetMethods (BindingFlags bindingFlags)
+               {
+                       return base.GetMethods (bindingFlags);
+               }
+
+               public override int MetadataToken {
+                       get {
+                               return base.MetadataToken;
+                       }
+               }
+#endif
        }
 
        internal class ModuleBuilderTokenGenerator : TokenGenerator {
@@ -834,11 +976,11 @@ namespace System.Reflection.Emit {
                        return mb.GetToken (str);
                }
 
-               public int GetToken (MemberInfo member) {
-                       return mb.GetToken (member);
+               public int GetToken (MemberInfo member, bool create_open_instance) {
+                       return mb.GetToken (member, create_open_instance);
                }
 
-               public int GetToken (MethodInfo method, Type[] opt_param_types) {
+               public int GetToken (MethodBase method, Type[] opt_param_types) {
                        return mb.GetToken (method, opt_param_types);
                }
 
@@ -848,3 +990,4 @@ namespace System.Reflection.Emit {
        }
 }
 
+#endif