File: system\reflection\methodinfo.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
// ==++==
// 
//   Copyright(c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
// <OWNER>Microsoft</OWNER>
// 
 
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
    }
}