Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Reflection / Emit / DynamicMethod.cs / 1305376 / DynamicMethod.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //[....] // namespace System.Reflection.Emit { using System; using System.Collections.Generic; using CultureInfo = System.Globalization.CultureInfo; using System.Reflection; using System.Security; using System.Security.Permissions; using System.Threading; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; [System.Runtime.InteropServices.ComVisible(true)] public sealed class DynamicMethod : MethodInfo { RuntimeType[] m_parameterTypes; internal IRuntimeMethodInfo m_methodHandle; RuntimeType m_returnType; DynamicILGenerator m_ilGenerator; DynamicILInfo m_DynamicILInfo; bool m_fInitLocals; internal RuntimeModule m_module; internal bool m_skipVisibility; internal RuntimeType m_typeOwner; // can be null // We want the creator of the DynamicMethod to control who has access to the // DynamicMethod (just like we do for delegates). However, a user can get to // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would // not be able to bound access to the DynamicMethod. Hence, we need to ensure that // we do not allow direct use of RTDynamicMethod. RTDynamicMethod m_dynMethod; // needed to keep the object alive during jitting // assigned by the DynamicResolver ctor internal DynamicResolver m_resolver; internal bool m_restrictedSkipVisibility; // The context when the method was created. We use this to do the RestrictedMemberAccess checks. // These checks are done when the method is compiled. This can happen at an arbitrary time, // when CreateDelegate or Invoke is called, or when another DynamicMethod executes OpCodes.Call. // We capture the creation context so that we can do the checks against the same context, // irrespective of when the method gets compiled. Note that the DynamicMethod does not know when // it is ready for use since there is not API which indictates that IL generation has completed. #if FEATURE_COMPRESSEDSTACK internal CompressedStack m_creationContext; #endif // FEATURE_COMPRESSEDSTACK private static InternalModuleBuilder s_anonymouslyHostedDynamicMethodsModule; private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object(); // // class initialization (ctor and init) // private DynamicMethod() { } [System.Security.SecuritySafeCritical] // auto-generated public DynamicMethod(string name, Type returnType, Type[] parameterTypes) { Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner null, // m false, // skipVisibility true); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated public DynamicMethod(string name, Type returnType, Type[] parameterTypes, bool restrictedSkipVisibility) { Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner null, // m restrictedSkipVisibility, true); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, false); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner m, // m false, // skipVisibility false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner m, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility); Init(name, attributes, callingConvention, returnType, parameterTypes, null, // owner m, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, false); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, // owner null, // m false, // skipVisibility false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, // owner null, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility); Init(name, attributes, callingConvention, returnType, parameterTypes, owner, // owner null, // m skipVisibility, false); // transparentMethod } // helpers for intialization static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention) { // only static public for method attributes if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); Contract.EndContractBlock(); // only standard or varargs supported if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); // vararg is not supported at the moment if (callingConvention == CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); } // We create a transparent assembly to host DynamicMethods. Since the assembly does not have any // non-public fields (or any fields at all), it is a safe anonymous assembly to host DynamicMethods [System.Security.SecurityCritical] // auto-generated private static RuntimeModule GetDynamicMethodsModule() { if (s_anonymouslyHostedDynamicMethodsModule != null) return s_anonymouslyHostedDynamicMethodsModule; lock (s_anonymouslyHostedDynamicMethodsModuleLock) { if (s_anonymouslyHostedDynamicMethodsModule != null) return s_anonymouslyHostedDynamicMethodsModule; ConstructorInfo transparencyCtor = typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes); CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, new object[0]); ListassemblyAttributes = new List (); assemblyAttributes.Add(transparencyAttribute); #if !FEATURE_CORECLR // On the desktop, we need to use the security rule set level 1 for anonymously hosted // dynamic methods. In level 2, transparency rules are strictly enforced, which leads to // errors when a fully trusted application causes a dynamic method to be generated that tries // to call a method with a LinkDemand or a SecurityCritical method. To retain compatibility // with the v2.0 and v3.x frameworks, these calls should be allowed. // // If this rule set was not explicitly called out, then the anonymously hosted dynamic methods // assembly would inherit the rule set from the creating assembly - which would cause it to // be level 2 because mscorlib.dll is using the level 2 rules. ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }); CustomAttributeBuilder securityRulesAttribute = new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level1 }); assemblyAttributes.Add(securityRulesAttribute); #endif // !FEATURE_CORECLR AssemblyName assemblyName = new AssemblyName("Anonymously Hosted DynamicMethods Assembly"); StackCrawlMark stackMark = StackCrawlMark.LookForMe; AssemblyBuilder assembly = AssemblyBuilder.InternalDefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run, null, null, null, null, null, ref stackMark, assemblyAttributes, SecurityContextSource.CurrentAssembly); AppDomain.PublishAnonymouslyHostedDynamicMethodsAssembly(assembly.GetNativeHandle()); // this always gets the internal module. s_anonymouslyHostedDynamicMethodsModule = (InternalModuleBuilder)assembly.ManifestModule; } return s_anonymouslyHostedDynamicMethodsModule; } [System.Security.SecurityCritical] // auto-generated private unsafe void Init(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] signature, Type owner, Module m, bool skipVisibility, bool transparentMethod) { DynamicMethod.CheckConsistency(attributes, callingConvention); // check and store the signature if (signature != null) { m_parameterTypes = new RuntimeType[signature.Length]; for (int i = 0; i < signature.Length; i++) { if (signature[i] == null) throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType; if ( m_parameterTypes[i] == null || !m_parameterTypes[i].IsRuntimeType || m_parameterTypes[i] == typeof(void) ) throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); } } else { m_parameterTypes = new RuntimeType[0]; } // check and store the return value m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : returnType.UnderlyingSystemType as RuntimeType; if ( (m_returnType == null) || !m_returnType.IsRuntimeType || m_returnType.IsByRef ) throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType")); if (transparentMethod) { Contract.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods"); m_module = GetDynamicMethodsModule(); if (skipVisibility) { m_restrictedSkipVisibility = true; #if FEATURE_COMPRESSEDSTACK m_creationContext = CompressedStack.Capture(); #endif // FEATURE_COMPRESSEDSTACK } } else { Contract.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set"); Contract.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly"); Contract.Assert(m == null || owner == null, "m and owner cannot both be set"); if (m != null) m_module = m.ModuleHandle.GetRuntimeModule(); else { if (owner != null && owner.UnderlyingSystemType != null && owner.UnderlyingSystemType.IsRuntimeType) { m_typeOwner = owner.UnderlyingSystemType.TypeHandle.GetRuntimeType(); if (m_typeOwner.HasElementType || m_typeOwner.ContainsGenericParameters || m_typeOwner.IsGenericParameter || m_typeOwner.IsInterface) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod")); m_module = (RuntimeModule)m_typeOwner.Module; } } m_skipVisibility = skipVisibility; } // initialize remaining fields m_ilGenerator = null; m_fInitLocals = true; m_methodHandle = null; if (name == null) throw new ArgumentNullException("name"); m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention); } [System.Security.SecurityCritical] // auto-generated static private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility) { if (m == null) throw new ArgumentNullException("m"); Contract.EndContractBlock(); RuntimeModule rtModule; ModuleBuilder mb = m as ModuleBuilder; if (mb != null) rtModule = mb.InternalModule; else rtModule = m as RuntimeModule; if (rtModule == null) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeModule"), "m"); } // The user cannot explicitly use this assembly if (rtModule == s_anonymouslyHostedDynamicMethodsModule) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"), "m"); // ask for member access if skip visibility if (skipVisibility) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); #if !FEATURE_CORECLR // ask for control evidence if outside of the caller assembly RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); if (m.Assembly != callingType.Assembly) { // Demand the permissions of the assembly where the DynamicMethod will live CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, m.Assembly.PermissionSet); } #else //FEATURE_CORECLR new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); #endif //FEATURE_CORECLR } [System.Security.SecurityCritical] // auto-generated static private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility) { if (owner == null) throw new ArgumentNullException("owner"); RuntimeType rtOwner = owner as RuntimeType; if (rtOwner == null) rtOwner = owner.UnderlyingSystemType as RuntimeType; if (rtOwner == null) throw new ArgumentNullException("owner", Environment.GetResourceString("Argument_MustBeRuntimeType")); // get the type the call is coming from RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); // ask for member access if skip visibility if (skipVisibility) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); else { // if the call is not coming from the same class ask for member access if (callingType != rtOwner) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); } #if !FEATURE_CORECLR // ask for control evidence if outside of the caller module if (rtOwner.Assembly != callingType.Assembly) { // Demand the permissions of the assembly where the DynamicMethod will live CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, owner.Assembly.PermissionSet); } #else //FEATURE_CORECLR new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); #endif //FEATURE_CORECLR } // // Delegate and method creation // [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public Delegate CreateDelegate(Type delegateType) { if (m_restrictedSkipVisibility) { // Compile the method since accessibility checks are done as part of compilation. GetMethodDescriptor(); System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); } MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, null, GetMethodDescriptor()); // stash this MethodInfo by brute force. d.StoreDynamicMethod(GetMethodInfo()); return d; } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public Delegate CreateDelegate(Type delegateType, Object target) { if (m_restrictedSkipVisibility) { // Compile the method since accessibility checks are done as part of compilation GetMethodDescriptor(); System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); } MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, target, GetMethodDescriptor()); // stash this MethodInfo by brute force. d.StoreDynamicMethod(GetMethodInfo()); return d; } // This is guaranteed to return a valid handle [System.Security.SecurityCritical] // auto-generated internal unsafe RuntimeMethodHandle GetMethodDescriptor() { if (m_methodHandle == null) { lock (this) { if (m_methodHandle == null) { if (m_DynamicILInfo != null) m_DynamicILInfo.GetCallableMethod(m_module, this); else { if (m_ilGenerator == null || m_ilGenerator.ILOffset == 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", Name)); m_ilGenerator.GetCallableMethod(m_module, this); } } } } return new RuntimeMethodHandle(m_methodHandle); } // // MethodInfo api. They mostly forward to RTDynamicMethod // public override String ToString() { return m_dynMethod.ToString(); } public override String Name { get { return m_dynMethod.Name; } } public override Type DeclaringType { get { return m_dynMethod.DeclaringType; } } public override Type ReflectedType { get { return m_dynMethod.ReflectedType; } } public override Module Module { get { return m_dynMethod.Module; } } // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } } public override MethodAttributes Attributes { get { return m_dynMethod.Attributes; } } public override CallingConventions CallingConvention { get { return m_dynMethod.CallingConvention; } } public override MethodInfo GetBaseDefinition() { return this; } [Pure] public override ParameterInfo[] GetParameters() { return m_dynMethod.GetParameters(); } public override MethodImplAttributes GetMethodImplementationFlags() { return m_dynMethod.GetMethodImplementationFlags(); } // // Security transparency accessors // // Since the dynamic method may not be JITed yet, we don't always have the runtime method handle // which is needed to determine the official runtime transparency status of the dynamic method. We // fall back to saying that the dynamic method matches the transparency of its containing module // until we get a JITed version, since dynamic methods cannot have attributes of their own. // public override bool IsSecurityCritical { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecurityCritical(this.m_methodHandle); } } public override bool IsSecuritySafeCritical { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecuritySafeCritical(this.m_methodHandle); } } public override bool IsSecurityTransparent { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecurityTransparent(this.m_methodHandle); } } [System.Security.SecuritySafeCritical] // auto-generated public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg")); Contract.EndContractBlock(); // // We do not demand any permission here because the caller already has access // to the current DynamicMethod object, and it could just as easily emit another // Transparent DynamicMethod to call the current DynamicMethod. // RuntimeMethodHandle method = GetMethodDescriptor(); // ignore obj since it's a static method // create a signature object Signature sig = new Signature( this.m_methodHandle, m_parameterTypes, m_returnType, CallingConvention); // verify arguments int formalCount = sig.Arguments.Length; int actualCount = (parameters != null) ? parameters.Length : 0; if (formalCount != actualCount) throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); // if we are here we passed all the previous checks. Time to look at the arguments Object retValue = null; if (actualCount > 0) { Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); retValue = RuntimeMethodHandle.InvokeMethodFast(this.m_methodHandle, null, arguments, sig, Attributes, null); // copy out. This should be made only if ByRef are present. for (int index = 0; index < actualCount; index++) parameters[index] = arguments[index]; } else { retValue = RuntimeMethodHandle.InvokeMethodFast(this.m_methodHandle, null, null, sig, Attributes, null); } GC.KeepAlive(this); return retValue; } public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_dynMethod.GetCustomAttributes(attributeType, inherit); } public override Object[] GetCustomAttributes(bool inherit) { return m_dynMethod.GetCustomAttributes(inherit); } public override bool IsDefined(Type attributeType, bool inherit) { return m_dynMethod.IsDefined(attributeType, inherit); } public override Type ReturnType { get { return m_dynMethod.ReturnType; } } public override ParameterInfo ReturnParameter { get { return m_dynMethod.ReturnParameter; } } public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return m_dynMethod.ReturnTypeCustomAttributes; } } // // DynamicMethod specific methods // public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName) { if (position < 0 || position > m_parameterTypes.Length) throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence")); position--; // it's 1 based. 0 is the return value if (position >= 0) { ParameterInfo[] parameters = m_dynMethod.LoadParameters(); parameters[position].SetName(parameterName); parameters[position].SetAttributes(attributes); } return null; } [System.Security.SecuritySafeCritical] // auto-generated public DynamicILInfo GetDynamicILInfo() { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); if (m_DynamicILInfo != null) return m_DynamicILInfo; return GetDynamicILInfo(new DynamicScope()); } [System.Security.SecurityCritical] // auto-generated internal DynamicILInfo GetDynamicILInfo(DynamicScope scope) { if (m_DynamicILInfo == null) { byte[] methodSignature = SignatureHelper.GetMethodSigHelper( null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); m_DynamicILInfo = new DynamicILInfo(scope, this, methodSignature); } return m_DynamicILInfo; } public ILGenerator GetILGenerator() { return GetILGenerator(64); } [System.Security.SecuritySafeCritical] // auto-generated public ILGenerator GetILGenerator(int streamSize) { if (m_ilGenerator == null) { byte[] methodSignature = SignatureHelper.GetMethodSigHelper( null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); m_ilGenerator = new DynamicILGenerator(this, methodSignature, streamSize); } return m_ilGenerator; } public bool InitLocals { get {return m_fInitLocals;} set {m_fInitLocals = value;} } // // Internal API // internal MethodInfo GetMethodInfo() { return m_dynMethod; } ////////////////////////////////////////////////////////////////////////////////////////////// // RTDynamicMethod // // this is actually the real runtime instance of a method info that gets used for invocation // We need this so we never leak the DynamicMethod out via an exception. // This way the DynamicMethod creator is the only one responsible for DynamicMethod access, // and can control exactly who gets access to it. // internal class RTDynamicMethod : MethodInfo { internal DynamicMethod m_owner; ParameterInfo[] m_parameters; String m_name; MethodAttributes m_attributes; CallingConventions m_callingConvention; // // ctors // private RTDynamicMethod() {} internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention) { m_owner = owner; m_name = name; m_attributes = attributes; m_callingConvention = callingConvention; } // // MethodInfo api // [System.Security.SecuritySafeCritical] // auto-generated public override String ToString() { return ReturnType.SigToString() + " " + ConstructName(); } public override String Name { get { return m_name; } } public override Type DeclaringType { get { return null; } } public override Type ReflectedType { get { return null; } } public override Module Module { [System.Security.SecuritySafeCritical] // auto-generated get { return m_owner.m_module; } } public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } } public override MethodAttributes Attributes { get { return m_attributes; } } public override CallingConventions CallingConvention { get { return m_callingConvention; } } public override MethodInfo GetBaseDefinition() { return this; } [Pure] public override ParameterInfo[] GetParameters() { ParameterInfo[] privateParameters = LoadParameters(); ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length]; Array.Copy(privateParameters, parameters, privateParameters.Length); return parameters; } public override MethodImplAttributes GetMethodImplementationFlags() { return MethodImplAttributes.IL | MethodImplAttributes.NoInlining; } public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { // We want the creator of the DynamicMethod to control who has access to the // DynamicMethod (just like we do for delegates). However, a user can get to // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would // not be able to bound access to the DynamicMethod. Hence, we do not allow // direct use of RTDynamicMethod. throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "this"); } public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { if (attributeType == null) throw new ArgumentNullException("attributeType"); Contract.EndContractBlock(); if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; else return new Object[0]; } public override Object[] GetCustomAttributes(bool inherit) { // support for MethodImplAttribute PCA return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; } public override bool IsDefined(Type attributeType, bool inherit) { if (attributeType == null) throw new ArgumentNullException("attributeType"); Contract.EndContractBlock(); if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) return true; else return false; } public override bool IsSecurityCritical { get { return m_owner.IsSecurityCritical; } } public override bool IsSecuritySafeCritical { get { return m_owner.IsSecuritySafeCritical; } } public override bool IsSecurityTransparent { get { return m_owner.IsSecurityTransparent; } } public override Type ReturnType { get { return m_owner.m_returnType; } } public override ParameterInfo ReturnParameter { get { return null; } } public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return GetEmptyCAHolder(); } } // // private implementation // internal ParameterInfo[] LoadParameters() { if (m_parameters == null) { Type[] parameterTypes = m_owner.m_parameterTypes; ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length]; for (int i = 0; i < parameterTypes.Length; i++) parameters[i] = new RuntimeParameterInfo(this, null, parameterTypes[i], i); if (m_parameters == null) // should we interlockexchange? m_parameters = parameters; } return m_parameters; } // private implementation of CA for the return type private ICustomAttributeProvider GetEmptyCAHolder() { return new EmptyCAHolder(); } /////////////////////////////////////////////////// // EmptyCAHolder private class EmptyCAHolder : ICustomAttributeProvider { internal EmptyCAHolder() {} Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit) { return new Object[0]; } Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) { return new Object[0]; } bool ICustomAttributeProvider.IsDefined (Type attributeType, bool inherit) { return false; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // [....] // namespace System.Reflection.Emit { using System; using System.Collections.Generic; using CultureInfo = System.Globalization.CultureInfo; using System.Reflection; using System.Security; using System.Security.Permissions; using System.Threading; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; [System.Runtime.InteropServices.ComVisible(true)] public sealed class DynamicMethod : MethodInfo { RuntimeType[] m_parameterTypes; internal IRuntimeMethodInfo m_methodHandle; RuntimeType m_returnType; DynamicILGenerator m_ilGenerator; DynamicILInfo m_DynamicILInfo; bool m_fInitLocals; internal RuntimeModule m_module; internal bool m_skipVisibility; internal RuntimeType m_typeOwner; // can be null // We want the creator of the DynamicMethod to control who has access to the // DynamicMethod (just like we do for delegates). However, a user can get to // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would // not be able to bound access to the DynamicMethod. Hence, we need to ensure that // we do not allow direct use of RTDynamicMethod. RTDynamicMethod m_dynMethod; // needed to keep the object alive during jitting // assigned by the DynamicResolver ctor internal DynamicResolver m_resolver; internal bool m_restrictedSkipVisibility; // The context when the method was created. We use this to do the RestrictedMemberAccess checks. // These checks are done when the method is compiled. This can happen at an arbitrary time, // when CreateDelegate or Invoke is called, or when another DynamicMethod executes OpCodes.Call. // We capture the creation context so that we can do the checks against the same context, // irrespective of when the method gets compiled. Note that the DynamicMethod does not know when // it is ready for use since there is not API which indictates that IL generation has completed. #if FEATURE_COMPRESSEDSTACK internal CompressedStack m_creationContext; #endif // FEATURE_COMPRESSEDSTACK private static InternalModuleBuilder s_anonymouslyHostedDynamicMethodsModule; private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object(); // // class initialization (ctor and init) // private DynamicMethod() { } [System.Security.SecuritySafeCritical] // auto-generated public DynamicMethod(string name, Type returnType, Type[] parameterTypes) { Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner null, // m false, // skipVisibility true); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated public DynamicMethod(string name, Type returnType, Type[] parameterTypes, bool restrictedSkipVisibility) { Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner null, // m restrictedSkipVisibility, true); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, false); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner m, // m false, // skipVisibility false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, // owner m, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility); Init(name, attributes, callingConvention, returnType, parameterTypes, null, // owner m, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, false); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, // owner null, // m false, // skipVisibility false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility); Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, // owner null, // m skipVisibility, false); // transparentMethod } [System.Security.SecuritySafeCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility); Init(name, attributes, callingConvention, returnType, parameterTypes, owner, // owner null, // m skipVisibility, false); // transparentMethod } // helpers for intialization static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention) { // only static public for method attributes if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); Contract.EndContractBlock(); // only standard or varargs supported if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); // vararg is not supported at the moment if (callingConvention == CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); } // We create a transparent assembly to host DynamicMethods. Since the assembly does not have any // non-public fields (or any fields at all), it is a safe anonymous assembly to host DynamicMethods [System.Security.SecurityCritical] // auto-generated private static RuntimeModule GetDynamicMethodsModule() { if (s_anonymouslyHostedDynamicMethodsModule != null) return s_anonymouslyHostedDynamicMethodsModule; lock (s_anonymouslyHostedDynamicMethodsModuleLock) { if (s_anonymouslyHostedDynamicMethodsModule != null) return s_anonymouslyHostedDynamicMethodsModule; ConstructorInfo transparencyCtor = typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes); CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, new object[0]); ListassemblyAttributes = new List (); assemblyAttributes.Add(transparencyAttribute); #if !FEATURE_CORECLR // On the desktop, we need to use the security rule set level 1 for anonymously hosted // dynamic methods. In level 2, transparency rules are strictly enforced, which leads to // errors when a fully trusted application causes a dynamic method to be generated that tries // to call a method with a LinkDemand or a SecurityCritical method. To retain compatibility // with the v2.0 and v3.x frameworks, these calls should be allowed. // // If this rule set was not explicitly called out, then the anonymously hosted dynamic methods // assembly would inherit the rule set from the creating assembly - which would cause it to // be level 2 because mscorlib.dll is using the level 2 rules. ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }); CustomAttributeBuilder securityRulesAttribute = new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level1 }); assemblyAttributes.Add(securityRulesAttribute); #endif // !FEATURE_CORECLR AssemblyName assemblyName = new AssemblyName("Anonymously Hosted DynamicMethods Assembly"); StackCrawlMark stackMark = StackCrawlMark.LookForMe; AssemblyBuilder assembly = AssemblyBuilder.InternalDefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run, null, null, null, null, null, ref stackMark, assemblyAttributes, SecurityContextSource.CurrentAssembly); AppDomain.PublishAnonymouslyHostedDynamicMethodsAssembly(assembly.GetNativeHandle()); // this always gets the internal module. s_anonymouslyHostedDynamicMethodsModule = (InternalModuleBuilder)assembly.ManifestModule; } return s_anonymouslyHostedDynamicMethodsModule; } [System.Security.SecurityCritical] // auto-generated private unsafe void Init(String name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] signature, Type owner, Module m, bool skipVisibility, bool transparentMethod) { DynamicMethod.CheckConsistency(attributes, callingConvention); // check and store the signature if (signature != null) { m_parameterTypes = new RuntimeType[signature.Length]; for (int i = 0; i < signature.Length; i++) { if (signature[i] == null) throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType; if ( m_parameterTypes[i] == null || !m_parameterTypes[i].IsRuntimeType || m_parameterTypes[i] == typeof(void) ) throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); } } else { m_parameterTypes = new RuntimeType[0]; } // check and store the return value m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : returnType.UnderlyingSystemType as RuntimeType; if ( (m_returnType == null) || !m_returnType.IsRuntimeType || m_returnType.IsByRef ) throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType")); if (transparentMethod) { Contract.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods"); m_module = GetDynamicMethodsModule(); if (skipVisibility) { m_restrictedSkipVisibility = true; #if FEATURE_COMPRESSEDSTACK m_creationContext = CompressedStack.Capture(); #endif // FEATURE_COMPRESSEDSTACK } } else { Contract.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set"); Contract.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly"); Contract.Assert(m == null || owner == null, "m and owner cannot both be set"); if (m != null) m_module = m.ModuleHandle.GetRuntimeModule(); else { if (owner != null && owner.UnderlyingSystemType != null && owner.UnderlyingSystemType.IsRuntimeType) { m_typeOwner = owner.UnderlyingSystemType.TypeHandle.GetRuntimeType(); if (m_typeOwner.HasElementType || m_typeOwner.ContainsGenericParameters || m_typeOwner.IsGenericParameter || m_typeOwner.IsInterface) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod")); m_module = (RuntimeModule)m_typeOwner.Module; } } m_skipVisibility = skipVisibility; } // initialize remaining fields m_ilGenerator = null; m_fInitLocals = true; m_methodHandle = null; if (name == null) throw new ArgumentNullException("name"); m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention); } [System.Security.SecurityCritical] // auto-generated static private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility) { if (m == null) throw new ArgumentNullException("m"); Contract.EndContractBlock(); RuntimeModule rtModule; ModuleBuilder mb = m as ModuleBuilder; if (mb != null) rtModule = mb.InternalModule; else rtModule = m as RuntimeModule; if (rtModule == null) { throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeModule"), "m"); } // The user cannot explicitly use this assembly if (rtModule == s_anonymouslyHostedDynamicMethodsModule) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"), "m"); // ask for member access if skip visibility if (skipVisibility) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); #if !FEATURE_CORECLR // ask for control evidence if outside of the caller assembly RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); if (m.Assembly != callingType.Assembly) { // Demand the permissions of the assembly where the DynamicMethod will live CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, m.Assembly.PermissionSet); } #else //FEATURE_CORECLR new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); #endif //FEATURE_CORECLR } [System.Security.SecurityCritical] // auto-generated static private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility) { if (owner == null) throw new ArgumentNullException("owner"); RuntimeType rtOwner = owner as RuntimeType; if (rtOwner == null) rtOwner = owner.UnderlyingSystemType as RuntimeType; if (rtOwner == null) throw new ArgumentNullException("owner", Environment.GetResourceString("Argument_MustBeRuntimeType")); // get the type the call is coming from RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); // ask for member access if skip visibility if (skipVisibility) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); else { // if the call is not coming from the same class ask for member access if (callingType != rtOwner) new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); } #if !FEATURE_CORECLR // ask for control evidence if outside of the caller module if (rtOwner.Assembly != callingType.Assembly) { // Demand the permissions of the assembly where the DynamicMethod will live CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, owner.Assembly.PermissionSet); } #else //FEATURE_CORECLR new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); #endif //FEATURE_CORECLR } // // Delegate and method creation // [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public Delegate CreateDelegate(Type delegateType) { if (m_restrictedSkipVisibility) { // Compile the method since accessibility checks are done as part of compilation. GetMethodDescriptor(); System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); } MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, null, GetMethodDescriptor()); // stash this MethodInfo by brute force. d.StoreDynamicMethod(GetMethodInfo()); return d; } [System.Security.SecuritySafeCritical] // auto-generated [System.Runtime.InteropServices.ComVisible(true)] public Delegate CreateDelegate(Type delegateType, Object target) { if (m_restrictedSkipVisibility) { // Compile the method since accessibility checks are done as part of compilation GetMethodDescriptor(); System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); } MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, target, GetMethodDescriptor()); // stash this MethodInfo by brute force. d.StoreDynamicMethod(GetMethodInfo()); return d; } // This is guaranteed to return a valid handle [System.Security.SecurityCritical] // auto-generated internal unsafe RuntimeMethodHandle GetMethodDescriptor() { if (m_methodHandle == null) { lock (this) { if (m_methodHandle == null) { if (m_DynamicILInfo != null) m_DynamicILInfo.GetCallableMethod(m_module, this); else { if (m_ilGenerator == null || m_ilGenerator.ILOffset == 0) throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", Name)); m_ilGenerator.GetCallableMethod(m_module, this); } } } } return new RuntimeMethodHandle(m_methodHandle); } // // MethodInfo api. They mostly forward to RTDynamicMethod // public override String ToString() { return m_dynMethod.ToString(); } public override String Name { get { return m_dynMethod.Name; } } public override Type DeclaringType { get { return m_dynMethod.DeclaringType; } } public override Type ReflectedType { get { return m_dynMethod.ReflectedType; } } public override Module Module { get { return m_dynMethod.Module; } } // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } } public override MethodAttributes Attributes { get { return m_dynMethod.Attributes; } } public override CallingConventions CallingConvention { get { return m_dynMethod.CallingConvention; } } public override MethodInfo GetBaseDefinition() { return this; } [Pure] public override ParameterInfo[] GetParameters() { return m_dynMethod.GetParameters(); } public override MethodImplAttributes GetMethodImplementationFlags() { return m_dynMethod.GetMethodImplementationFlags(); } // // Security transparency accessors // // Since the dynamic method may not be JITed yet, we don't always have the runtime method handle // which is needed to determine the official runtime transparency status of the dynamic method. We // fall back to saying that the dynamic method matches the transparency of its containing module // until we get a JITed version, since dynamic methods cannot have attributes of their own. // public override bool IsSecurityCritical { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecurityCritical(this.m_methodHandle); } } public override bool IsSecuritySafeCritical { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecuritySafeCritical(this.m_methodHandle); } } public override bool IsSecurityTransparent { [System.Security.SecuritySafeCritical] // auto-generated get { GetMethodDescriptor(); return RuntimeMethodHandle.IsSecurityTransparent(this.m_methodHandle); } } [System.Security.SecuritySafeCritical] // auto-generated public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg")); Contract.EndContractBlock(); // // We do not demand any permission here because the caller already has access // to the current DynamicMethod object, and it could just as easily emit another // Transparent DynamicMethod to call the current DynamicMethod. // RuntimeMethodHandle method = GetMethodDescriptor(); // ignore obj since it's a static method // create a signature object Signature sig = new Signature( this.m_methodHandle, m_parameterTypes, m_returnType, CallingConvention); // verify arguments int formalCount = sig.Arguments.Length; int actualCount = (parameters != null) ? parameters.Length : 0; if (formalCount != actualCount) throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); // if we are here we passed all the previous checks. Time to look at the arguments Object retValue = null; if (actualCount > 0) { Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); retValue = RuntimeMethodHandle.InvokeMethodFast(this.m_methodHandle, null, arguments, sig, Attributes, null); // copy out. This should be made only if ByRef are present. for (int index = 0; index < actualCount; index++) parameters[index] = arguments[index]; } else { retValue = RuntimeMethodHandle.InvokeMethodFast(this.m_methodHandle, null, null, sig, Attributes, null); } GC.KeepAlive(this); return retValue; } public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_dynMethod.GetCustomAttributes(attributeType, inherit); } public override Object[] GetCustomAttributes(bool inherit) { return m_dynMethod.GetCustomAttributes(inherit); } public override bool IsDefined(Type attributeType, bool inherit) { return m_dynMethod.IsDefined(attributeType, inherit); } public override Type ReturnType { get { return m_dynMethod.ReturnType; } } public override ParameterInfo ReturnParameter { get { return m_dynMethod.ReturnParameter; } } public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return m_dynMethod.ReturnTypeCustomAttributes; } } // // DynamicMethod specific methods // public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName) { if (position < 0 || position > m_parameterTypes.Length) throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence")); position--; // it's 1 based. 0 is the return value if (position >= 0) { ParameterInfo[] parameters = m_dynMethod.LoadParameters(); parameters[position].SetName(parameterName); parameters[position].SetAttributes(attributes); } return null; } [System.Security.SecuritySafeCritical] // auto-generated public DynamicILInfo GetDynamicILInfo() { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); if (m_DynamicILInfo != null) return m_DynamicILInfo; return GetDynamicILInfo(new DynamicScope()); } [System.Security.SecurityCritical] // auto-generated internal DynamicILInfo GetDynamicILInfo(DynamicScope scope) { if (m_DynamicILInfo == null) { byte[] methodSignature = SignatureHelper.GetMethodSigHelper( null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); m_DynamicILInfo = new DynamicILInfo(scope, this, methodSignature); } return m_DynamicILInfo; } public ILGenerator GetILGenerator() { return GetILGenerator(64); } [System.Security.SecuritySafeCritical] // auto-generated public ILGenerator GetILGenerator(int streamSize) { if (m_ilGenerator == null) { byte[] methodSignature = SignatureHelper.GetMethodSigHelper( null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); m_ilGenerator = new DynamicILGenerator(this, methodSignature, streamSize); } return m_ilGenerator; } public bool InitLocals { get {return m_fInitLocals;} set {m_fInitLocals = value;} } // // Internal API // internal MethodInfo GetMethodInfo() { return m_dynMethod; } ////////////////////////////////////////////////////////////////////////////////////////////// // RTDynamicMethod // // this is actually the real runtime instance of a method info that gets used for invocation // We need this so we never leak the DynamicMethod out via an exception. // This way the DynamicMethod creator is the only one responsible for DynamicMethod access, // and can control exactly who gets access to it. // internal class RTDynamicMethod : MethodInfo { internal DynamicMethod m_owner; ParameterInfo[] m_parameters; String m_name; MethodAttributes m_attributes; CallingConventions m_callingConvention; // // ctors // private RTDynamicMethod() {} internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention) { m_owner = owner; m_name = name; m_attributes = attributes; m_callingConvention = callingConvention; } // // MethodInfo api // [System.Security.SecuritySafeCritical] // auto-generated public override String ToString() { return ReturnType.SigToString() + " " + ConstructName(); } public override String Name { get { return m_name; } } public override Type DeclaringType { get { return null; } } public override Type ReflectedType { get { return null; } } public override Module Module { [System.Security.SecuritySafeCritical] // auto-generated get { return m_owner.m_module; } } public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } } public override MethodAttributes Attributes { get { return m_attributes; } } public override CallingConventions CallingConvention { get { return m_callingConvention; } } public override MethodInfo GetBaseDefinition() { return this; } [Pure] public override ParameterInfo[] GetParameters() { ParameterInfo[] privateParameters = LoadParameters(); ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length]; Array.Copy(privateParameters, parameters, privateParameters.Length); return parameters; } public override MethodImplAttributes GetMethodImplementationFlags() { return MethodImplAttributes.IL | MethodImplAttributes.NoInlining; } public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { // We want the creator of the DynamicMethod to control who has access to the // DynamicMethod (just like we do for delegates). However, a user can get to // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would // not be able to bound access to the DynamicMethod. Hence, we do not allow // direct use of RTDynamicMethod. throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "this"); } public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { if (attributeType == null) throw new ArgumentNullException("attributeType"); Contract.EndContractBlock(); if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; else return new Object[0]; } public override Object[] GetCustomAttributes(bool inherit) { // support for MethodImplAttribute PCA return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; } public override bool IsDefined(Type attributeType, bool inherit) { if (attributeType == null) throw new ArgumentNullException("attributeType"); Contract.EndContractBlock(); if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) return true; else return false; } public override bool IsSecurityCritical { get { return m_owner.IsSecurityCritical; } } public override bool IsSecuritySafeCritical { get { return m_owner.IsSecuritySafeCritical; } } public override bool IsSecurityTransparent { get { return m_owner.IsSecurityTransparent; } } public override Type ReturnType { get { return m_owner.m_returnType; } } public override ParameterInfo ReturnParameter { get { return null; } } public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return GetEmptyCAHolder(); } } // // private implementation // internal ParameterInfo[] LoadParameters() { if (m_parameters == null) { Type[] parameterTypes = m_owner.m_parameterTypes; ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length]; for (int i = 0; i < parameterTypes.Length; i++) parameters[i] = new RuntimeParameterInfo(this, null, parameterTypes[i], i); if (m_parameters == null) // should we interlockexchange? m_parameters = parameters; } return m_parameters; } // private implementation of CA for the return type private ICustomAttributeProvider GetEmptyCAHolder() { return new EmptyCAHolder(); } /////////////////////////////////////////////////// // EmptyCAHolder private class EmptyCAHolder : ICustomAttributeProvider { internal EmptyCAHolder() {} Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit) { return new Object[0]; } Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) { return new Object[0]; } bool ICustomAttributeProvider.IsDefined (Type attributeType, bool inherit) { return false; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FileDetails.cs
- SqlIdentifier.cs
- ToolStripLabel.cs
- StringUtil.cs
- MethodExpression.cs
- DnsPermission.cs
- DialogDivider.cs
- CompositeDataBoundControl.cs
- ExclusiveCanonicalizationTransform.cs
- BindingCompleteEventArgs.cs
- HttpApplicationFactory.cs
- QilNode.cs
- PixelFormatConverter.cs
- GB18030Encoding.cs
- DataGridViewColumnStateChangedEventArgs.cs
- PolyLineSegment.cs
- StrokeFIndices.cs
- AttributeData.cs
- CommentAction.cs
- AppDomainFactory.cs
- ObjectTag.cs
- Comparer.cs
- WindowsStatusBar.cs
- SqlDuplicator.cs
- CommittableTransaction.cs
- DataPointer.cs
- Literal.cs
- HttpHandlerActionCollection.cs
- HGlobalSafeHandle.cs
- FileDialog.cs
- CounterCreationDataCollection.cs
- ShaderRenderModeValidation.cs
- util.cs
- SqlPersonalizationProvider.cs
- HttpCapabilitiesEvaluator.cs
- InlinedLocationReference.cs
- SqlLiftWhereClauses.cs
- NumericUpDownAcceleration.cs
- PageAsyncTaskManager.cs
- ValidationError.cs
- VisualProxy.cs
- XamlSerializationHelper.cs
- OverflowException.cs
- WebSysDescriptionAttribute.cs
- StickyNoteAnnotations.cs
- PropertyConverter.cs
- WindowsScroll.cs
- PerformanceCounterCategory.cs
- RelationshipType.cs
- NavigationPropertyEmitter.cs
- DelegateTypeInfo.cs
- UnknownWrapper.cs
- ExpressionEditorAttribute.cs
- TdsParameterSetter.cs
- ProxyAttribute.cs
- VarRefManager.cs
- XmlSchemaType.cs
- WebServiceEnumData.cs
- ScriptServiceAttribute.cs
- XmlNodeComparer.cs
- OdbcEnvironmentHandle.cs
- ReflectionPermission.cs
- InputBuffer.cs
- SortQuery.cs
- BrowserCapabilitiesCodeGenerator.cs
- XmlValidatingReaderImpl.cs
- Directory.cs
- MessageBox.cs
- Html32TextWriter.cs
- MarginCollapsingState.cs
- AttributeData.cs
- Icon.cs
- RewritingPass.cs
- XmlnsDictionary.cs
- PtsHelper.cs
- SpStreamWrapper.cs
- CacheMode.cs
- WindowsTreeView.cs
- EntityDataSourceWizardForm.cs
- TextBoxRenderer.cs
- MemberRelationshipService.cs
- WindowsSpinner.cs
- SqlMultiplexer.cs
- CodeIterationStatement.cs
- IDQuery.cs
- ChangeProcessor.cs
- UserControl.cs
- GridViewColumnHeaderAutomationPeer.cs
- DataReceivedEventArgs.cs
- TranslateTransform.cs
- CSharpCodeProvider.cs
- SafeFileMappingHandle.cs
- XmlIlGenerator.cs
- Registry.cs
- InvalidEnumArgumentException.cs
- FontStyles.cs
- Int32Storage.cs
- TextDecoration.cs
- RadioButton.cs
- SynchronizationHandlesCodeDomSerializer.cs