X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection%2FMonoMethod.cs;h=b1079d6be1810d4ae4299c2d4058df1269a4160b;hb=9f3ce4b1e55eb8485dc54458924a9173f76233de;hp=0c030675207ade136aa4b2a78ca9c6fd36e42407;hpb=43861d2253544114e3aac5ee1a0c5b0357d9f9cd;p=mono.git diff --git a/mcs/class/corlib/System.Reflection/MonoMethod.cs b/mcs/class/corlib/System.Reflection/MonoMethod.cs index 0c030675207..b1079d6be18 100644 --- a/mcs/class/corlib/System.Reflection/MonoMethod.cs +++ b/mcs/class/corlib/System.Reflection/MonoMethod.cs @@ -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,20 +43,67 @@ namespace System.Reflection { internal struct MonoMethodInfo { - internal Type parent; - internal Type ret; +#pragma warning disable 649 + private Type parent; + private Type ret; internal MethodAttributes attrs; internal MethodImplAttributes iattrs; - internal CallingConventions callconv; + private CallingConventions callconv; +#pragma warning restore 649 [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void get_method_info (IntPtr handle, out MonoMethodInfo info); + static extern void get_method_info (IntPtr handle, out MonoMethodInfo info); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern ParameterInfo[] get_parameter_info (IntPtr handle); + static extern int get_method_attributes (IntPtr handle); + + internal static MonoMethodInfo GetMethodInfo (IntPtr handle) + { + MonoMethodInfo info; + MonoMethodInfo.get_method_info (handle, out info); + return info; + } + + internal static Type GetDeclaringType (IntPtr handle) + { + return GetMethodInfo (handle).parent; + } + + internal static Type GetReturnType (IntPtr handle) + { + return GetMethodInfo (handle).ret; + } + + internal static MethodAttributes GetAttributes (IntPtr handle) + { + return (MethodAttributes)get_method_attributes (handle); + } + + internal static CallingConventions GetCallingConvention (IntPtr handle) + { + return GetMethodInfo (handle).callconv; + } + + internal static MethodImplAttributes GetMethodImplementationFlags (IntPtr handle) + { + return GetMethodInfo (handle).iattrs; + } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static extern ParameterInfo[] get_parameter_info (IntPtr handle, MemberInfo member); + + static internal ParameterInfo[] GetParametersInfo (IntPtr handle, MemberInfo member) + { + return get_parameter_info (handle, member); + } [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern UnmanagedMarshal get_retval_marshal (IntPtr handle); + static extern UnmanagedMarshal get_retval_marshal (IntPtr handle); + + static internal ParameterInfo GetReturnParameterInfo (MonoMethod method) + { + return new ParameterInfo (GetReturnType (method.mhandle), method, get_retval_marshal (method.mhandle)); + } }; /* @@ -65,9 +113,11 @@ namespace System.Reflection { [Serializable()] internal class MonoMethod : MethodInfo, ISerializable { +#pragma warning disable 649 internal IntPtr mhandle; string name; Type reftype; +#pragma warning restore 649 internal MonoMethod () { } @@ -77,42 +127,55 @@ namespace System.Reflection { } [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern MonoMethod get_base_definition (MonoMethod method); + internal static extern string get_name (MethodBase method); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + 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 new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle)); + return MonoMethodInfo.GetReturnParameterInfo (this); } } -#endif public override Type ReturnType { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.ret; + return MonoMethodInfo.GetReturnType (mhandle); } } public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { - return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle)); + return MonoMethodInfo.GetReturnParameterInfo (this); } } - public override MethodImplAttributes GetMethodImplementationFlags() { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.iattrs; + public override MethodImplAttributes GetMethodImplementationFlags () + { + return MonoMethodInfo.GetMethodImplementationFlags (mhandle); } - public override ParameterInfo[] GetParameters() { - return MonoMethodInfo.get_parameter_info (mhandle); + public override ParameterInfo[] GetParameters () + { + 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; } /* @@ -120,41 +183,60 @@ namespace System.Reflection { * binder to match the types of the method signature. */ [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal extern Object InternalInvoke (Object obj, Object[] parameters); - + internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc); + public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { if (binder == null) binder = Binder.DefaultBinder; - ParameterInfo[] pinfo = GetParameters (); - if (!Binder.ConvertArgs (binder, parameters, pinfo, culture)) - throw new ArgumentException ("parameters"); + /*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"); + + if ((invokeAttr & BindingFlags.ExactBinding) == 0) { + if (!Binder.ConvertArgs (binder, parameters, pinfo, culture)) + throw new ArgumentException ("failed to convert parameters"); + } else { + for (int i = 0; i < pinfo.Length; i++) + if (parameters[i].GetType() != pinfo[i].ParameterType) + 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 (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; try { - return InternalInvoke (obj, parameters); - } catch (InvalidOperationException) { - throw; - } catch (TargetException) { + // The ex argument is used to distinguish exceptions thrown by the icall + // from the exceptions thrown by the called method (which need to be + // wrapped in TargetInvocationException). + o = InternalInvoke (obj, parameters, out exc); + } catch (ThreadAbortException) { throw; -#if NET_2_0 - } catch (ThreadAbortException e) { +#if NET_2_1 + } catch (MethodAccessException) { throw; #endif } catch (Exception e) { throw new TargetInvocationException (e); } + + if (exc != null) + throw exc; + return o; } public override RuntimeMethodHandle MethodHandle { @@ -162,17 +244,13 @@ namespace System.Reflection { } public override MethodAttributes Attributes { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.attrs; + return MonoMethodInfo.GetAttributes (mhandle); } } public override CallingConventions CallingConvention { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.callconv; + return MonoMethodInfo.GetCallingConvention (mhandle); } } @@ -183,14 +261,14 @@ namespace System.Reflection { } public override Type DeclaringType { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.parent; + return MonoMethodInfo.GetDeclaringType (mhandle); } } public override string Name { get { - return name; + if (name != null) + return name; + return get_name (this); } } @@ -214,8 +292,7 @@ namespace System.Reflection { /* MS.NET doesn't report MethodImplAttribute */ - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); + MonoMethodInfo info = MonoMethodInfo.GetMethodInfo (mhandle); if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0) count ++; if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) @@ -238,16 +315,20 @@ namespace System.Reflection { return attrs; } + static bool ShouldPrintFullName (Type type) { + return type.IsClass && (!type.IsPointer || + (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested)); + } + public override string ToString () { StringBuilder sb = new StringBuilder (); - if (ReturnType.IsClass && ReturnType.Namespace != String.Empty) { - sb.Append (ReturnType.Namespace); - sb.Append ("."); - } - sb.Append (ReturnType.Name); + Type retType = ReturnType; + if (ShouldPrintFullName (retType)) + sb.Append (retType.ToString ()); + else + 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 ("["); @@ -258,7 +339,6 @@ namespace System.Reflection { } sb.Append ("]"); } -#endif sb.Append ("("); ParameterInfo[] p = GetParameters (); for (int i = 0; i < p.Length; ++i) { @@ -268,14 +348,19 @@ namespace System.Reflection { bool byref = pt.IsByRef; if (byref) pt = pt.GetElementType (); - if (pt.IsClass && pt.Namespace != String.Empty) { - sb.Append (pt.Namespace); - sb.Append ("."); - } - sb.Append (pt.Name); + if (ShouldPrintFullName (pt)) + sb.Append (pt.ToString ()); + else + sb.Append (pt.Name); if (byref) sb.Append (" ByRef"); } + if ((CallingConvention & CallingConventions.VarArgs) != 0) { + if (p.Length > 0) + sb.Append (", "); + sb.Append ("..."); + } + sb.Append (")"); return sb.ToString (); } @@ -284,17 +369,37 @@ namespace System.Reflection { // ISerializable public void GetObjectData(SerializationInfo info, StreamingContext context) { - ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method); + Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition + ? GetGenericArguments () : null; + MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments); } -#if NET_2_0 || BOOTSTRAP_NET_2_0 - public override MethodInfo MakeGenericMethod (Type [] types) + public override MethodInfo MakeGenericMethod (Type [] methodInstantiation) { - if (types == null) - throw new ArgumentNullException ("types"); - MethodInfo ret = MakeGenericMethod_impl (types); + if (methodInstantiation == null) + throw new ArgumentNullException ("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) - throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, types.Length)); + throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length)); return ret; } @@ -336,29 +441,40 @@ 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 GetCustomAttributesData () { + return CustomAttributeData.GetCustomAttributes (this); + } #endif } internal class MonoCMethod : ConstructorInfo, ISerializable { +#pragma warning disable 649 internal IntPtr mhandle; string name; Type reftype; +#pragma warning restore 649 - public override MethodImplAttributes GetMethodImplementationFlags() { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.iattrs; + public override MethodImplAttributes GetMethodImplementationFlags () + { + return MonoMethodInfo.GetMethodImplementationFlags (mhandle); + } + + public override ParameterInfo[] GetParameters () + { + return MonoMethodInfo.GetParametersInfo (mhandle, this); } - public override ParameterInfo[] GetParameters() { - return MonoMethodInfo.get_parameter_info (mhandle); + internal override int GetParameterCount () + { + var pi = MonoMethodInfo.GetParametersInfo (mhandle, this); + return pi == null ? 0 : pi.Length; } /* @@ -366,32 +482,59 @@ namespace System.Reflection { * to match the types of the method signature. */ [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal extern Object InternalInvoke (Object obj, Object[] parameters); + internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc); public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { if (binder == null) binder = Binder.DefaultBinder; + ParameterInfo[] pinfo = GetParameters (); - if (!Binder.ConvertArgs (binder, parameters, pinfo, culture)) - throw new ArgumentException ("parameters"); + if ((parameters == null && pinfo.Length != 0) || (parameters != null && parameters.Length != pinfo.Length)) + throw new TargetParameterCountException ("parameters do not match signature"); + + if ((invokeAttr & BindingFlags.ExactBinding) == 0) { + if (!Binder.ConvertArgs (binder, parameters, pinfo, culture)) + throw new ArgumentException ("failed to convert parameters"); + } else { + for (int i = 0; i < pinfo.Length; i++) + if (parameters[i].GetType() != pinfo[i].ParameterType) + 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 (obj == null && DeclaringType.ContainsGenericParameters) + throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true."); + + 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)); + } + + Exception exc = null; + object o = null; try { - return InternalInvoke (obj, parameters); - } catch (InvalidOperationException) { - throw; - } catch (TargetException) { + o = InternalInvoke (obj, parameters, out exc); +#if NET_2_1 + } catch (MethodAccessException) { throw; +#endif } catch (Exception e) { throw new TargetInvocationException (e); } + + if (exc != null) + throw exc; + return (obj == null) ? o : null; } public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { @@ -403,17 +546,13 @@ namespace System.Reflection { } public override MethodAttributes Attributes { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.attrs; + return MonoMethodInfo.GetAttributes (mhandle); } } public override CallingConventions CallingConvention { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.callconv; + return MonoMethodInfo.GetCallingConvention (mhandle); } } @@ -424,14 +563,14 @@ namespace System.Reflection { } public override Type DeclaringType { get { - MonoMethodInfo info; - MonoMethodInfo.get_method_info (mhandle, out info); - return info.parent; + return MonoMethodInfo.GetDeclaringType (mhandle); } } public override string Name { get { - return name; + if (name != null) + return name; + return MonoMethod.get_name (this); } } @@ -447,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 (); @@ -464,6 +601,8 @@ namespace System.Reflection { sb.Append (", "); sb.Append (p[i].ParameterType.Name); } + if (CallingConvention == CallingConventions.Any) + sb.Append (", ..."); sb.Append (")"); return sb.ToString (); } @@ -471,7 +610,13 @@ namespace System.Reflection { // ISerializable public void GetObjectData(SerializationInfo info, StreamingContext context) { - ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor); + MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor); } + +#if NET_4_0 + public override IList GetCustomAttributesData () { + return CustomAttributeData.GetCustomAttributes (this); + } +#endif } }