Fix continuation not being scheduled because of too early and too greedy disposing.
[mono.git] / mcs / class / corlib / System.Reflection / MonoMethod.cs
index e9f88fa73beedbd72b0c6e578eb05250c6e060f5..b1079d6be1810d4ae4299c2d4058df1269a4160b 100644 (file)
@@ -28,6 +28,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Collections.Generic;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
@@ -42,15 +43,20 @@ namespace System.Reflection {
        
        internal struct MonoMethodInfo 
        {
+#pragma warning disable 649    
                private Type parent;
                private Type ret;
                internal MethodAttributes attrs;
                internal MethodImplAttributes iattrs;
                private CallingConventions callconv;
+#pragma warning restore 649            
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
                
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               static extern int get_method_attributes (IntPtr handle);
+               
                internal static MonoMethodInfo GetMethodInfo (IntPtr handle)
                {
                        MonoMethodInfo info;
@@ -70,7 +76,7 @@ namespace System.Reflection {
 
                internal static MethodAttributes GetAttributes (IntPtr handle)
                {
-                       return GetMethodInfo (handle).attrs;
+                       return (MethodAttributes)get_method_attributes (handle);
                }
 
                internal static CallingConventions GetCallingConvention (IntPtr handle)
@@ -124,20 +130,23 @@ namespace System.Reflection {
                internal static extern string get_name (MethodBase method);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal static extern MonoMethod get_base_definition (MonoMethod method);
+               internal static extern MonoMethod get_base_method (MonoMethod method, bool definition);
 
                public override MethodInfo GetBaseDefinition ()
                {
-                       return get_base_definition (this);
+                       return get_base_method (this, true);
+               }
+
+               internal override MethodInfo GetBaseMethod ()
+               {
+                       return get_base_method (this, false);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                public override ParameterInfo ReturnParameter {
                        get {
                                return MonoMethodInfo.GetReturnParameterInfo (this);
                        }
                }
-#endif
 
                public override Type ReturnType {
                        get {
@@ -157,7 +166,16 @@ namespace System.Reflection {
 
                public override ParameterInfo[] GetParameters ()
                {
-                       return MonoMethodInfo.GetParametersInfo (mhandle, this);
+                       ParameterInfo[] src = MonoMethodInfo.GetParametersInfo (mhandle, this);
+                       ParameterInfo[] res = new ParameterInfo [src.Length];
+                       src.CopyTo (res, 0);
+                       return res;
+               }
+               
+               internal override int GetParameterCount ()
+               {
+                       var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
+                       return pi == null ? 0 : pi.Length;
                }
 
                /*
@@ -171,7 +189,8 @@ namespace System.Reflection {
                {
                        if (binder == null)
                                binder = Binder.DefaultBinder;
-                       ParameterInfo[] pinfo = GetParameters ();
+                       /*Avoid allocating an array every time*/
+                       ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
 
                        if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length))
                                throw new TargetParameterCountException ("parameters do not match signature");
@@ -194,10 +213,8 @@ namespace System.Reflection {
                        }
 #endif
 
-#if NET_2_0
                        if (ContainsGenericParameters)
                                throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
-#endif
 
                        Exception exc;
                        object o = null;
@@ -207,10 +224,8 @@ namespace System.Reflection {
                                // from the exceptions thrown by the called method (which need to be
                                // wrapped in TargetInvocationException).
                                o = InternalInvoke (obj, parameters, out exc);
-#if NET_2_0
                        } catch (ThreadAbortException) {
                                throw;
-#endif
 #if NET_2_1
                        } catch (MethodAccessException) {
                                throw;
@@ -302,11 +317,7 @@ namespace System.Reflection {
 
                static bool ShouldPrintFullName (Type type) {
                        return type.IsClass && (!type.IsPointer ||
-#if NET_2_0
                                (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested));
-#else
-                               !type.GetElementType ().IsPrimitive);
-#endif
                }
 
                public override string ToString () {
@@ -318,7 +329,6 @@ namespace System.Reflection {
                                sb.Append (retType.Name);
                        sb.Append (" ");
                        sb.Append (Name);
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                        if (IsGenericMethod) {
                                Type[] gen_params = GetGenericArguments ();
                                sb.Append ("[");
@@ -329,7 +339,6 @@ namespace System.Reflection {
                                }
                                sb.Append ("]");
                        }
-#endif
                        sb.Append ("(");
                        ParameterInfo[] p = GetParameters ();
                        for (int i = 0; i < p.Length; ++i) {
@@ -360,23 +369,33 @@ namespace System.Reflection {
                // ISerializable
                public void GetObjectData(SerializationInfo info, StreamingContext context) 
                {
-#if NET_2_0
                        Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition
                                ? GetGenericArguments () : null;
                        MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments);
-#else
-                       MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
-#endif
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
                {
                        if (methodInstantiation == null)
                                throw new ArgumentNullException ("methodInstantiation");
-                       foreach (Type type in methodInstantiation)
+
+                       if (!IsGenericMethodDefinition)
+                               throw new InvalidOperationException ("not a generic method definition");
+
+                       /*FIXME add GetGenericArgumentsLength() internal vcall to speed this up*/
+                       if (GetGenericArguments ().Length != methodInstantiation.Length)
+                               throw new ArgumentException ("Incorrect length");
+
+                       bool hasUserType = false;
+                       foreach (Type type in methodInstantiation) {
                                if (type == null)
                                        throw new ArgumentNullException ();
+                               if (!(type is MonoType))
+                                       hasUserType = true;
+                       }
+
+                       if (hasUserType)
+                               return new MethodOnTypeBuilderInst (this, methodInstantiation);
 
                        MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
                        if (ret == null)
@@ -422,12 +441,15 @@ namespace System.Reflection {
                                return DeclaringType.ContainsGenericParameters;
                        }
                }
-#endif
 
-#if NET_2_0
                public override MethodBody GetMethodBody () {
                        return GetMethodBody (mhandle);
                }
+
+#if NET_4_0
+               public override IList<CustomAttributeData> GetCustomAttributesData () {
+                       return CustomAttributeData.GetCustomAttributes (this);
+               }
 #endif
        }
        
@@ -449,6 +471,12 @@ namespace System.Reflection {
                        return MonoMethodInfo.GetParametersInfo (mhandle, this);
                }
 
+               internal override int GetParameterCount ()
+               {
+                       var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
+                       return pi == null ? 0 : pi.Length;
+               }
+
                /*
                 * InternalInvoke() receives the parameters corretcly converted by the binder
                 * to match the types of the method signature.
@@ -475,17 +503,17 @@ namespace System.Reflection {
                                                throw new ArgumentException ("parameters do not match signature");
                        }
 
+#if !NET_2_1
                        if (SecurityManager.SecurityEnabled) {
                                // sadly Attributes doesn't tell us which kind of security action this is so
                                // we must do it the hard way - and it also means that we can skip calling
                                // Attribute (which is another an icall)
                                SecurityManager.ReflectedLinkDemandInvoke (this);
                        }
+#endif
 
-#if NET_2_0
                        if (obj == null && DeclaringType.ContainsGenericParameters)
                                throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
-#endif
 
                        if ((invokeAttr & BindingFlags.CreateInstance) != 0 && DeclaringType.IsAbstract) {
                                throw new MemberAccessException (String.Format ("Cannot create an instance of {0} because it is an abstract class", DeclaringType));
@@ -558,11 +586,9 @@ namespace System.Reflection {
                        return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
                }
 
-#if NET_2_0
                public override MethodBody GetMethodBody () {
                        return GetMethodBody (mhandle);
                }
-#endif
 
                public override string ToString () {
                        StringBuilder sb = new StringBuilder ();
@@ -586,5 +612,11 @@ namespace System.Reflection {
                {
                        MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);
                }
+
+#if NET_4_0
+               public override IList<CustomAttributeData> GetCustomAttributesData () {
+                       return CustomAttributeData.GetCustomAttributes (this);
+               }
+#endif
        }
 }