Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ModuleBuilder.cs
index 376ce6df68d680cdbf6d2c449b7ccdd6d8c60147..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;
@@ -45,6 +46,7 @@ namespace System.Reflection.Emit {
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_ModuleBuilder))]
        [ClassInterface (ClassInterfaceType.None)]
+       [StructLayout (LayoutKind.Sequential)]
        public class ModuleBuilder : Module, _ModuleBuilder {
 
 #pragma warning disable 169, 414
@@ -66,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;
@@ -89,6 +91,7 @@ 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);
 
@@ -101,19 +104,12 @@ namespace System.Reflection.Emit {
                        }
 
                        if (emitSymbolInfo) {
-#if MOONLIGHT
-                               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)
-                                       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 });
-#endif
                                string fileName = fqname;
                                if (assemblyb.AssemblyDir != null)
                                        fileName = Path.Combine (assemblyb.AssemblyDir, fileName);
@@ -264,6 +260,8 @@ 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);
@@ -535,7 +533,7 @@ 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 ();
                }
@@ -600,6 +598,8 @@ namespace System.Reflection.Emit {
                {
                        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));
                }
 
@@ -652,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 (MethodInfo method, Type[] opt_param_types) {
+               internal int GetToken (MemberInfo member, bool create_open_instance) {
+                       return getToken (this, member, create_open_instance);
+               }
+
+               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);
                }
 
                /*
@@ -818,6 +825,142 @@ namespace System.Reflection.Emit {
                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
        }
 
@@ -833,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);
                }
 
@@ -847,3 +990,4 @@ namespace System.Reflection.Emit {
        }
 }
 
+#endif