// ==++== // // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== // [....] // namespace System.Reflection { using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Diagnostics.Tracing; 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); } [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public static bool operator !=(MethodInfo left, MethodInfo right) { return !(left == right); } #endif // !FEATURE_CORECLR #if FEATURE_NETCORE || !FEATURE_CORECLR public override bool Equals(object obj) { return base.Equals(obj); } public override int GetHashCode() { return base.GetHashCode(); } #endif //FEATURE_NETCORE || !FEATURE_CORECLR #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 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(); } } [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)] #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 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); #if !FEATURE_CORECLR if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage)) { FrameworkEventSource.Log.MethodName(GetDeclaringTypeInternal().GetFullNameForEtw(), GetFullNameForEtw()); } #endif return m_name; } } [System.Security.SecuritySafeCritical] internal override String GetFullNameForEtw() { if (m_name == null) return 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 #if !FEATURE_CORECLR [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] #endif 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 #pragma warning disable 618 [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)] #pragma warning restore 618 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 #if !FEATURE_CORECLR if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage)) { FrameworkEventSource.Log.MethodInfoInvoke(GetRuntimeType() != null ? GetRuntimeType().GetFullNameForEtw() : "", GetFullNameForEtw()); } #endif 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); #if !FEATURE_CORECLR if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage)) { FrameworkEventSource.Log.MethodInfoInvoke(GetRuntimeType() != null ? GetRuntimeType().GetFullNameForEtw() : "", GetFullNameForEtw()); } #endif 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"); #if !FEATURE_CORECLR if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage)) { FrameworkEventSource.Log.BeginMethodInfoCreateDelegate(GetRuntimeType() != null ? GetRuntimeType().GetFullNameForEtw() : "", GetFullNameForEtw(),rtType.GetFullNameForEtw()); } #endif Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark); if (d == null) { throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth")); } #if !FEATURE_CORECLR if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage)) { FrameworkEventSource.Log.EndMethodInfoCreateDelegate(GetRuntimeType() != null ? GetRuntimeType().GetFullNameForEtw() : "", GetFullNameForEtw(),rtType.GetFullNameForEtw()); } #endif 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.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 } }