summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/MethodInfo.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/MethodInfo.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/MethodInfo.cs1062
1 files changed, 1062 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/MethodInfo.cs b/src/mscorlib/src/System/Reflection/MethodInfo.cs
new file mode 100644
index 0000000000..2dd7defab5
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MethodInfo.cs
@@ -0,0 +1,1062 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+//
+
+namespace System.Reflection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
+ using System.Runtime;
+ using System.Runtime.InteropServices;
+ using System.Runtime.ConstrainedExecution;
+#if FEATURE_REMOTING
+ using System.Runtime.Remoting.Metadata;
+#endif //FEATURE_REMOTING
+ using System.Runtime.Serialization;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Text;
+ using System.Threading;
+ using MemberListType = System.RuntimeType.MemberListType;
+ using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+ using System.Runtime.CompilerServices;
+
+ [Serializable]
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComDefaultInterface(typeof(_MethodInfo))]
+#pragma warning disable 618
+ [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
+#pragma warning restore 618
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public abstract class MethodInfo : MethodBase, _MethodInfo
+ {
+ #region Constructor
+ protected MethodInfo() { }
+ #endregion
+
+#if !FEATURE_CORECLR
+ public static bool operator ==(MethodInfo left, MethodInfo right)
+ {
+ if (ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null ||
+ left is RuntimeMethodInfo || right is RuntimeMethodInfo)
+ {
+ return false;
+ }
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(MethodInfo left, MethodInfo right)
+ {
+ return !(left == right);
+ }
+#endif // !FEATURE_CORECLR
+
+ public override bool Equals(object obj)
+ {
+ return base.Equals(obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ #region MemberInfo Overrides
+ public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Method; } }
+ #endregion
+
+ #region Public Abstract\Virtual Members
+ public virtual Type ReturnType { get { throw new NotImplementedException(); } }
+
+ public virtual ParameterInfo ReturnParameter { get { throw new NotImplementedException(); } }
+
+ public abstract ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
+
+ public abstract MethodInfo GetBaseDefinition();
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public override Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public virtual MethodInfo GetGenericMethodDefinition() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+
+ public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+
+ public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+ public virtual Delegate CreateDelegate(Type delegateType, Object target) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
+ #endregion
+
+#if !FEATURE_CORECLR
+ Type _MethodInfo.GetType()
+ {
+ return base.GetType();
+ }
+
+ void _MethodInfo.GetTypeInfoCount(out uint pcTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _MethodInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _MethodInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ {
+ throw new NotImplementedException();
+ }
+
+ // If you implement this method, make sure to include _MethodInfo.Invoke in VM\DangerousAPIs.h and
+ // include _MethodInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
+ void _MethodInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ {
+ throw new NotImplementedException();
+ }
+#endif
+ }
+
+ [Serializable]
+ internal sealed class RuntimeMethodInfo : MethodInfo, ISerializable, IRuntimeMethodInfo
+ {
+ #region Private Data Members
+ private IntPtr m_handle;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private string m_name;
+ private string m_toString;
+ private ParameterInfo[] m_parameters;
+ private ParameterInfo m_returnParameter;
+ private BindingFlags m_bindingFlags;
+ private MethodAttributes m_methodAttributes;
+ private Signature m_signature;
+ private RuntimeType m_declaringType;
+ private object m_keepalive;
+ private INVOCATION_FLAGS m_invocationFlags;
+
+#if FEATURE_APPX
+ private bool IsNonW8PFrameworkAPI()
+ {
+ if (m_declaringType.IsArray && IsPublic && !IsStatic)
+ return false;
+
+ RuntimeAssembly rtAssembly = GetRuntimeAssembly();
+ if (rtAssembly.IsFrameworkAssembly())
+ {
+ int ctorToken = rtAssembly.InvocableAttributeCtorToken;
+ if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
+ !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
+ return true;
+ }
+
+ if (GetRuntimeType().IsNonW8PFrameworkAPI())
+ return true;
+
+ if (IsGenericMethod && !IsGenericMethodDefinition)
+ {
+ foreach (Type t in GetGenericArguments())
+ {
+ if (((RuntimeType)t).IsNonW8PFrameworkAPI())
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ internal override bool IsDynamicallyInvokable
+ {
+ get
+ {
+ return !AppDomain.ProfileAPICheck || !IsNonW8PFrameworkAPI();
+ }
+ }
+#endif
+
+ internal INVOCATION_FLAGS InvocationFlags
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
+ {
+ INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
+
+ Type declaringType = DeclaringType;
+
+ //
+ // first take care of all the NO_INVOKE cases.
+ if (ContainsGenericParameters ||
+ ReturnType.IsByRef ||
+ (declaringType != null && declaringType.ContainsGenericParameters) ||
+ ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
+ ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
+ {
+ // We don't need other flags if this method cannot be invoked
+ invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
+ }
+ else
+ {
+ // this should be an invocable method, determine the other flags that participate in invocation
+ invocationFlags = RuntimeMethodHandle.GetSecurityFlags(this);
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0)
+ {
+ if ( (Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
+ (declaringType != null && declaringType.NeedsReflectionSecurityCheck) )
+ {
+ // If method is non-public, or declaring type is not visible
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+ else if (IsGenericMethod)
+ {
+ Type[] genericArguments = GetGenericArguments();
+
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ if (genericArguments[i].NeedsReflectionSecurityCheck)
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+#if FEATURE_APPX
+ if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
+#endif // FEATURE_APPX
+
+ m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
+ }
+
+ return m_invocationFlags;
+ }
+ }
+ #endregion
+
+ #region Constructor
+ [System.Security.SecurityCritical] // auto-generated
+ internal RuntimeMethodInfo(
+ RuntimeMethodHandleInternal handle, RuntimeType declaringType,
+ RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive)
+ {
+ Contract.Ensures(!m_handle.IsNull());
+
+ Contract.Assert(!handle.IsNullHandle());
+ Contract.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
+
+ m_bindingFlags = bindingFlags;
+ m_declaringType = declaringType;
+ m_keepalive = keepalive;
+ m_handle = handle.Value;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_methodAttributes = methodAttributes;
+ }
+ #endregion
+
+#if FEATURE_REMOTING
+ #region Legacy Remoting Cache
+ // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
+ // This member is currently being used by Remoting for caching remoting data. If you
+ // need to cache data here, talk to the Remoting team to work out a mechanism, so that
+ // both caching systems can happily work together.
+ private RemotingMethodCachedData m_cachedData;
+
+ internal RemotingMethodCachedData RemotingCache
+ {
+ get
+ {
+ // This grabs an internal copy of m_cachedData and uses
+ // that instead of looking at m_cachedData directly because
+ // the cache may get cleared asynchronously. This prevents
+ // us from having to take a lock.
+ RemotingMethodCachedData cache = m_cachedData;
+ if (cache == null)
+ {
+ cache = new RemotingMethodCachedData(this);
+ RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
+ if (ret != null)
+ cache = ret;
+ }
+ return cache;
+ }
+ }
+ #endregion
+#endif //FEATURE_REMOTING
+
+ #region Private Methods
+ RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ return new RuntimeMethodHandleInternal(m_handle);
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ParameterInfo[] FetchNonReturnParameters()
+ {
+ if (m_parameters == null)
+ m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
+
+ return m_parameters;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ParameterInfo FetchReturnParameter()
+ {
+ if (m_returnParameter == null)
+ m_returnParameter = RuntimeParameterInfo.GetReturnParameter(this, this, Signature);
+
+ return m_returnParameter;
+ }
+ #endregion
+
+ #region Internal Members
+ internal override string FormatNameAndSig(bool serialization)
+ {
+ // Serialization uses ToString to resolve MethodInfo overloads.
+ StringBuilder sbName = new StringBuilder(Name);
+
+ // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads.
+ // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString().
+ TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic;
+
+ if (IsGenericMethod)
+ sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format));
+
+ sbName.Append("(");
+ sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
+ sbName.Append(")");
+
+ return sbName.ToString();
+ }
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal override bool CacheEquals(object o)
+ {
+ RuntimeMethodInfo m = o as RuntimeMethodInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_handle == m_handle;
+ }
+
+ internal Signature Signature
+ {
+ get
+ {
+ if (m_signature == null)
+ m_signature = new Signature(this, m_declaringType);
+
+ return m_signature;
+ }
+ }
+
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+
+ // Differs from MethodHandle in that it will return a valid handle even for reflection only loaded types
+ internal RuntimeMethodHandle GetMethodHandle()
+ {
+ return new RuntimeMethodHandle(this);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ internal RuntimeMethodInfo GetParentDefinition()
+ {
+ if (!IsVirtual || m_declaringType.IsInterface)
+ return null;
+
+ RuntimeType parent = (RuntimeType)m_declaringType.BaseType;
+
+ if (parent == null)
+ return null;
+
+ int slot = RuntimeMethodHandle.GetSlot(this);
+
+ if (RuntimeTypeHandle.GetNumVirtuals(parent) <= slot)
+ return null;
+
+ return (RuntimeMethodInfo)RuntimeType.GetMethodBase(parent, RuntimeTypeHandle.GetMethodAt(parent, slot));
+ }
+
+ // Unlike DeclaringType, this will return a valid type even for global methods
+ internal RuntimeType GetDeclaringTypeInternal()
+ {
+ return m_declaringType;
+ }
+
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ if (m_toString == null)
+ m_toString = ReturnType.FormatTypeName() + " " + FormatNameAndSig();
+
+ return m_toString;
+ }
+
+ public override int GetHashCode()
+ {
+ // See RuntimeMethodInfo.Equals() below.
+ if (IsGenericMethod)
+ return ValueType.GetHashCodeOfPtr(m_handle);
+ else
+ return base.GetHashCode();
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public override bool Equals(object obj)
+ {
+ if (!IsGenericMethod)
+ return obj == (object)this;
+
+ // We cannot do simple object identity comparisons for generic methods.
+ // Equals will be called in CerHashTable when RuntimeType+RuntimeTypeCache.GetGenericMethodInfo()
+ // retrive items from and insert items into s_methodInstantiations which is a CerHashtable.
+
+ RuntimeMethodInfo mi = obj as RuntimeMethodInfo;
+
+ if (mi == null || !mi.IsGenericMethod)
+ return false;
+
+ // now we know that both operands are generic methods
+
+ IRuntimeMethodInfo handle1 = RuntimeMethodHandle.StripMethodInstantiation(this);
+ IRuntimeMethodInfo handle2 = RuntimeMethodHandle.StripMethodInstantiation(mi);
+ if (handle1.Value.Value != handle2.Value.Value)
+ return false;
+
+ Type[] lhs = GetGenericArguments();
+ Type[] rhs = mi.GetGenericArguments();
+
+ if (lhs.Length != rhs.Length)
+ return false;
+
+ for (int i = 0; i < lhs.Length; i++)
+ {
+ if (lhs[i] != rhs[i])
+ return false;
+ }
+
+ if (DeclaringType != mi.DeclaringType)
+ return false;
+
+ if (ReflectedType != mi.ReflectedType)
+ return false;
+
+ return true;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException("attributeType");
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException("attributeType");
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region MemberInfo Overrides
+ public override String Name
+ {
+ [System.Security.SecuritySafeCritical] // auto-generated
+ get
+ {
+ if (m_name == null)
+ m_name = RuntimeMethodHandle.GetName(this);
+
+ return m_name;
+ }
+ }
+
+ public override Type DeclaringType
+ {
+ get
+ {
+ if (m_reflectedTypeCache.IsGlobal)
+ return null;
+
+ return m_declaringType;
+ }
+ }
+
+ public override Type ReflectedType
+ {
+ get
+ {
+ if (m_reflectedTypeCache.IsGlobal)
+ return null;
+
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ public override MemberTypes MemberType { get { return MemberTypes.Method; } }
+ public override int MetadataToken
+ {
+ [System.Security.SecuritySafeCritical] // auto-generated
+ get { return RuntimeMethodHandle.GetMethodDef(this); }
+ }
+ public override Module Module { get { return GetRuntimeModule(); } }
+ internal RuntimeType GetRuntimeType() { return m_declaringType; }
+ internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
+ internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
+
+ public override bool IsSecurityCritical
+ {
+ get { return RuntimeMethodHandle.IsSecurityCritical(this); }
+ }
+ public override bool IsSecuritySafeCritical
+ {
+ get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); }
+ }
+ public override bool IsSecurityTransparent
+ {
+ get { return RuntimeMethodHandle.IsSecurityTransparent(this); }
+ }
+ #endregion
+
+ #region MethodBase Overrides
+ [System.Security.SecuritySafeCritical] // auto-generated
+ internal override ParameterInfo[] GetParametersNoCopy()
+ {
+ FetchNonReturnParameters();
+
+ return m_parameters;
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [System.Diagnostics.Contracts.Pure]
+ public override ParameterInfo[] GetParameters()
+ {
+ FetchNonReturnParameters();
+
+ if (m_parameters.Length == 0)
+ return m_parameters;
+
+ ParameterInfo[] ret = new ParameterInfo[m_parameters.Length];
+
+ Array.Copy(m_parameters, ret, m_parameters.Length);
+
+ return ret;
+ }
+
+ public override MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return RuntimeMethodHandle.GetImplAttributes(this);
+ }
+
+ internal bool IsOverloaded
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetMethodList(MemberListType.CaseSensitive, Name).Length > 1;
+ }
+ }
+
+ public override RuntimeMethodHandle MethodHandle
+ {
+ get
+ {
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
+ return new RuntimeMethodHandle(this);
+ }
+ }
+
+ public override MethodAttributes Attributes { get { return m_methodAttributes; } }
+
+ public override CallingConventions CallingConvention
+ {
+ get
+ {
+ return Signature.CallingConvention;
+ }
+ }
+
+ [System.Security.SecuritySafeCritical] // overrides SafeCritical member
+#if !FEATURE_CORECLR
+#pragma warning disable 618
+ [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)]
+#pragma warning restore 618
+#endif
+ public override MethodBody GetMethodBody()
+ {
+ MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
+ if (mb != null)
+ mb.m_methodBase = this;
+ return mb;
+ }
+ #endregion
+
+ #region Invocation Logic(On MemberBase)
+ private void CheckConsistency(Object target)
+ {
+ // only test instance methods
+ if ((m_methodAttributes & MethodAttributes.Static) != MethodAttributes.Static)
+ {
+ if (!m_declaringType.IsInstanceOfType(target))
+ {
+ if (target == null)
+ throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg"));
+ else
+ throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch"));
+ }
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private void ThrowNoInvokeException()
+ {
+ // method is ReflectionOnly
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
+ }
+ // method is on a class that contains stack pointers
+ else if ((InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS) != 0)
+ {
+ throw new NotSupportedException();
+ }
+ // method is vararg
+ else if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
+ {
+ throw new NotSupportedException();
+ }
+ // method is generic or on a generic class
+ else if (DeclaringType.ContainsGenericParameters || ContainsGenericParameters)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenParam"));
+ }
+ // method is abstract class
+ else if (IsAbstract)
+ {
+ throw new MemberAccessException();
+ }
+ // ByRef return are not allowed in reflection
+ else if (ReturnType.IsByRef)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_ByRefReturn"));
+ }
+
+ throw new TargetException();
+ }
+
+ [System.Security.SecuritySafeCritical]
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
+
+ #region Security Check
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+#if FEATURE_APPX
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
+ if (caller != null && !caller.IsSafeForReflection())
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
+ }
+#endif
+
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
+ {
+#if !FEATURE_CORECLR
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0)
+ CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess);
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
+#endif // !FEATURE_CORECLR
+ RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags);
+ }
+ #endregion
+
+ return UnsafeInvokeInternal(obj, parameters, arguments);
+ }
+
+ [System.Security.SecurityCritical]
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
+
+ return UnsafeInvokeInternal(obj, parameters, arguments);
+ }
+
+ [System.Security.SecurityCritical]
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
+ {
+ if (arguments == null || arguments.Length == 0)
+ return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
+ else
+ {
+ Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
+
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+
+ return retValue;
+ }
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ private object[] InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ Signature sig = Signature;
+
+ // get the signature
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ // INVOCATION_FLAGS_CONTAINS_STACK_POINTERS means that the struct (either the declaring type or the return type)
+ // contains pointers that point to the stack. This is either a ByRef or a TypedReference. These structs cannot
+ // be boxed and thus cannot be invoked through reflection which only deals with boxed value type objects.
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS)) != 0)
+ ThrowNoInvokeException();
+
+ // check basic method consistency. This call will throw if there are problems in the target/method relationship
+ CheckConsistency(obj);
+
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
+
+ if (actualCount != 0)
+ return CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ else
+ return null;
+ }
+
+ #endregion
+
+ #region MethodInfo Overrides
+ public override Type ReturnType
+ {
+ get { return Signature.ReturnType; }
+ }
+
+ public override ICustomAttributeProvider ReturnTypeCustomAttributes
+ {
+ get { return ReturnParameter; }
+ }
+
+ public override ParameterInfo ReturnParameter
+ {
+ [System.Security.SecuritySafeCritical] // auto-generated
+ get
+ {
+ Contract.Ensures(m_returnParameter != null);
+
+ FetchReturnParameter();
+ return m_returnParameter as ParameterInfo;
+ }
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public override MethodInfo GetBaseDefinition()
+ {
+ if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface)
+ return this;
+
+ int slot = RuntimeMethodHandle.GetSlot(this);
+ RuntimeType declaringType = (RuntimeType)DeclaringType;
+ RuntimeType baseDeclaringType = declaringType;
+ RuntimeMethodHandleInternal baseMethodHandle = new RuntimeMethodHandleInternal();
+
+ do {
+ int cVtblSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
+
+ if (cVtblSlots <= slot)
+ break;
+
+ baseMethodHandle = RuntimeTypeHandle.GetMethodAt(declaringType, slot);
+ baseDeclaringType = declaringType;
+
+ declaringType = (RuntimeType)declaringType.BaseType;
+ } while (declaringType != null);
+
+ return(MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle);
+ }
+
+ [System.Security.SecuritySafeCritical]
+ public override Delegate CreateDelegate(Type delegateType)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // This API existed in v1/v1.1 and only expected to create closed
+ // instance delegates. Constrain the call to BindToMethodInfo to
+ // open delegates only for backwards compatibility. But we'll allow
+ // relaxed signature checking and open static delegates because
+ // there's no ambiguity there (the caller would have to explicitly
+ // pass us a static method or a method with a non-exact signature
+ // and the only change in behavior from v1.1 there is that we won't
+ // fail the call).
+ return CreateDelegateInternal(
+ delegateType,
+ null,
+ DelegateBindingFlags.OpenDelegateOnly | DelegateBindingFlags.RelaxedSignature,
+ ref stackMark);
+ }
+
+ [System.Security.SecuritySafeCritical]
+ public override Delegate CreateDelegate(Type delegateType, Object target)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // This API is new in Whidbey and allows the full range of delegate
+ // flexability (open or closed delegates binding to static or
+ // instance methods with relaxed signature checking). The delegate
+ // can also be closed over null. There's no ambiguity with all these
+ // options since the caller is providing us a specific MethodInfo.
+ return CreateDelegateInternal(
+ delegateType,
+ target,
+ DelegateBindingFlags.RelaxedSignature,
+ ref stackMark);
+ }
+
+ [System.Security.SecurityCritical]
+ private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark)
+ {
+ // Validate the parameters.
+ if (delegateType == null)
+ throw new ArgumentNullException("delegateType");
+ Contract.EndContractBlock();
+
+ RuntimeType rtType = delegateType as RuntimeType;
+ if (rtType == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "delegateType");
+
+ if (!rtType.IsDelegate())
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "delegateType");
+
+ Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark);
+ if (d == null)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ }
+
+ return d;
+ }
+
+ #endregion
+
+ #region Generics
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation)
+ {
+ if (methodInstantiation == null)
+ throw new ArgumentNullException("methodInstantiation");
+ Contract.EndContractBlock();
+
+ RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length];
+
+ if (!IsGenericMethodDefinition)
+ throw new InvalidOperationException(
+ Environment.GetResourceString("Arg_NotGenericMethodDefinition", this));
+
+ for (int i = 0; i < methodInstantiation.Length; i++)
+ {
+ Type methodInstantiationElem = methodInstantiation[i];
+
+ if (methodInstantiationElem == null)
+ throw new ArgumentNullException();
+
+ RuntimeType rtMethodInstantiationElem = methodInstantiationElem as RuntimeType;
+
+ if (rtMethodInstantiationElem == null)
+ {
+ Type[] methodInstantiationCopy = new Type[methodInstantiation.Length];
+ for (int iCopy = 0; iCopy < methodInstantiation.Length; iCopy++)
+ methodInstantiationCopy[iCopy] = methodInstantiation[iCopy];
+ methodInstantiation = methodInstantiationCopy;
+ return System.Reflection.Emit.MethodBuilderInstantiation.MakeGenericMethod(this, methodInstantiation);
+ }
+
+ methodInstantionRuntimeType[i] = rtMethodInstantiationElem;
+ }
+
+ RuntimeType[] genericParameters = GetGenericArgumentsInternal();
+
+ RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters);
+
+ MethodInfo ret = null;
+
+ try
+ {
+ ret = RuntimeType.GetMethodBase(ReflectedTypeInternal,
+ RuntimeMethodHandle.GetStubIfNeeded(new RuntimeMethodHandleInternal(this.m_handle), m_declaringType, methodInstantionRuntimeType)) as MethodInfo;
+ }
+ catch (VerificationException e)
+ {
+ RuntimeType.ValidateGenericArguments(this, methodInstantionRuntimeType, e);
+ throw;
+ }
+
+ return ret;
+ }
+
+ internal RuntimeType[] GetGenericArgumentsInternal()
+ {
+ return RuntimeMethodHandle.GetMethodInstantiationInternal(this);
+ }
+
+ public override Type[] GetGenericArguments()
+ {
+ Type[] types = RuntimeMethodHandle.GetMethodInstantiationPublic(this);
+
+ if (types == null)
+ {
+ types = EmptyArray<Type>.Value;
+ }
+ return types;
+ }
+
+ public override MethodInfo GetGenericMethodDefinition()
+ {
+ if (!IsGenericMethod)
+ throw new InvalidOperationException();
+ Contract.EndContractBlock();
+
+ return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo;
+ }
+
+ public override bool IsGenericMethod
+ {
+ get { return RuntimeMethodHandle.HasMethodInstantiation(this); }
+ }
+
+ public override bool IsGenericMethodDefinition
+ {
+ get { return RuntimeMethodHandle.IsGenericMethodDefinition(this); }
+ }
+
+ public override bool ContainsGenericParameters
+ {
+ get
+ {
+ if (DeclaringType != null && DeclaringType.ContainsGenericParameters)
+ return true;
+
+ if (!IsGenericMethod)
+ return false;
+
+ Type[] pis = GetGenericArguments();
+ for (int i = 0; i < pis.Length; i++)
+ {
+ if (pis[i].ContainsGenericParameters)
+ return true;
+ }
+
+ return false;
+ }
+ }
+ #endregion
+
+ #region ISerializable Implementation
+ [System.Security.SecurityCritical] // auto-generated
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException("info");
+ Contract.EndContractBlock();
+
+ if (m_reflectedTypeCache.IsGlobal)
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
+
+ MemberInfoSerializationHolder.GetSerializationInfo(
+ info,
+ Name,
+ ReflectedTypeInternal,
+ ToString(),
+ SerializationToString(),
+ MemberTypes.Method,
+ IsGenericMethod & !IsGenericMethodDefinition ? GetGenericArguments() : null);
+ }
+
+ internal string SerializationToString()
+ {
+ return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
+ }
+ #endregion
+
+ #region Legacy Internal
+ internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark)
+ {
+ IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark);
+
+ if (method == null)
+ return null;
+
+ return RuntimeType.GetMethodBase(method);
+ }
+ #endregion
+ }
+}