X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection%2FMonoMethod.cs;h=1e084107fa5769c6bfd6a941aed8a53bc7c813c2;hb=c91a6cee78b8b5e9dab56f10d4656a5aa3a40b09;hp=39b1ac6640209b7f6eb2412a7203fc19e6509ed3;hpb=1fabd87b02f8d2e359150ed7a9e92613e60383bc;p=mono.git diff --git a/mcs/class/corlib/System.Reflection/MonoMethod.cs b/mcs/class/corlib/System.Reflection/MonoMethod.cs index 39b1ac66402..1e084107fa5 100644 --- a/mcs/class/corlib/System.Reflection/MonoMethod.cs +++ b/mcs/class/corlib/System.Reflection/MonoMethod.cs @@ -34,6 +34,9 @@ using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Reflection.Emit; using System.Security; +using System.Threading; +using System.Text; + namespace System.Reflection { @@ -62,9 +65,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 () { } @@ -73,6 +78,9 @@ namespace System.Reflection { this.mhandle = mhandle.Value; } + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern string get_name (MethodBase method); + [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern MonoMethod get_base_definition (MonoMethod method); @@ -117,37 +125,63 @@ 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"); + 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) { + // 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); +#if NET_2_0 + } catch (ThreadAbortException) { throw; - } catch (TargetException) { +#endif +#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 { @@ -183,7 +217,9 @@ namespace System.Reflection { } public override string Name { get { - return name; + if (name != null) + return name; + return get_name (this); } } @@ -231,56 +267,87 @@ namespace System.Reflection { return attrs; } + 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 () { - string parms = ""; + StringBuilder sb = new StringBuilder (); + 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 ("["); + for (int j = 0; j < gen_params.Length; j++) { + if (j > 0) + sb.Append (","); + sb.Append (gen_params [j].Name); + } + sb.Append ("]"); + } +#endif + sb.Append ("("); ParameterInfo[] p = GetParameters (); for (int i = 0; i < p.Length; ++i) { if (i > 0) - parms = parms + ", "; + sb.Append (", "); Type pt = p[i].ParameterType; bool byref = pt.IsByRef; if (byref) pt = pt.GetElementType (); - if (pt.IsClass && pt.Namespace != "") - parms = parms + pt.Namespace + "." + pt.Name; + if (ShouldPrintFullName (pt)) + sb.Append (pt.ToString ()); else - parms = parms + pt.Name; + sb.Append (pt.Name); if (byref) - parms += " ByRef"; + sb.Append (" ByRef"); } - if (ReturnType.IsClass && ReturnType.Namespace != "") - return ReturnType.Namespace + "." + ReturnType.Name + " " + Name + "(" + parms + ")"; - string generic = ""; -#if NET_2_0 || BOOTSTRAP_NET_2_0 - if (IsGenericMethod) { - Type[] gen_params = GetGenericArguments (); - generic = "["; - for (int j = 0; j < gen_params.Length; j++) { - if (j > 0) - generic += ","; - generic += gen_params [j].Name; - } - generic += "]"; + if ((CallingConvention & CallingConventions.VarArgs) != 0) { + if (p.Length > 0) + sb.Append (", "); + sb.Append ("..."); } -#endif - return ReturnType.Name + " " + Name + generic + "(" + parms + ")"; + + sb.Append (")"); + return sb.ToString (); } // ISerializable public void GetObjectData(SerializationInfo info, StreamingContext context) { - ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method); +#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 [] 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"); + foreach (Type type in methodInstantiation) + if (type == null) + throw new ArgumentNullException (); + + 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; } @@ -333,9 +400,11 @@ namespace System.Reflection { 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; @@ -352,15 +421,26 @@ 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 (SecurityManager.SecurityEnabled) { // sadly Attributes doesn't tell us which kind of security action this is so @@ -369,15 +449,31 @@ namespace System.Reflection { SecurityManager.ReflectedLinkDemandInvoke (this); } +#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)); + } + + 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) { @@ -417,7 +513,9 @@ namespace System.Reflection { } public override string Name { get { - return name; + if (name != null) + return name; + return MonoMethod.get_name (this); } } @@ -433,20 +531,6 @@ namespace System.Reflection { return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit); } -#if NET_2_0 || BOOTSTRAP_NET_2_0 - public override bool IsGenericMethodDefinition { - get { - return false; - } - } - - public override bool IsGenericMethod { - get { - return false; - } - } -#endif - #if NET_2_0 public override MethodBody GetMethodBody () { return GetMethodBody (mhandle); @@ -454,20 +538,24 @@ namespace System.Reflection { #endif public override string ToString () { - string parms = ""; + StringBuilder sb = new StringBuilder (); + sb.Append ("Void "); + sb.Append (Name); + sb.Append ("("); ParameterInfo[] p = GetParameters (); for (int i = 0; i < p.Length; ++i) { if (i > 0) - parms = parms + ", "; - parms = parms + p [i].ParameterType.Name; + sb.Append (", "); + sb.Append (p[i].ParameterType.Name); } - return "Void "+Name+"("+parms+")"; + sb.Append (")"); + return sb.ToString (); } // ISerializable public void GetObjectData(SerializationInfo info, StreamingContext context) { - ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor); + MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor); } } }