The Labs \ Source Viewer \ SSCLI \ System.Reflection.Emit \ EmptyCAHolder

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Reflection.Emit
  16. {
  17.     using System;
  18.     using CultureInfo = System.Globalization.CultureInfo;
  19.     using System.Reflection;
  20.     using System.Security;
  21.     using System.Security.Permissions;
  22.     using System.Threading;
  23.     using System.Runtime.CompilerServices;
  24.    
  25.     [System.Runtime.InteropServices.ComVisible(true)]
  26.     public sealed class DynamicMethod : MethodInfo
  27.     {
  28.         RuntimeType[] m_parameterTypes;
  29.         RuntimeType m_returnType;
  30.         DynamicILGenerator m_ilGenerator;
  31.         DynamicILInfo m_DynamicILInfo;
  32.         bool m_fInitLocals;
  33.         internal RuntimeMethodHandle m_method;
  34.         internal ModuleHandle m_module;
  35.         internal bool m_skipVisibility;
  36.         internal RuntimeType m_typeOwner;
  37.         RTDynamicMethod m_dynMethod;
  38.         // needed to keep the object alive during jitting
  39.         // assigned by the DynamicResolver ctor
  40.         internal DynamicResolver m_resolver;
  41.        
  42.         //
  43.         // class initialization (ctor and init)
  44.         //
  45.        
  46.         private DynamicMethod()
  47.         {
  48.         }
  49.        
  50.         public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m)
  51.         {
  52.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  53.             DynamicMethod.PerformSecurityCheck(m, ref stackMark, false);
  54.             Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, m, false);
  55.         }
  56.        
  57.         public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility)
  58.         {
  59.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  60.             DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility);
  61.             Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, m, skipVisibility);
  62.         }
  63.        
  64.         public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility)
  65.         {
  66.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  67.             DynamicMethod.PerformSecurityCheck(m, ref stackMark, skipVisibility);
  68.             Init(name, attributes, callingConvention, returnType, parameterTypes, null, m, skipVisibility);
  69.         }
  70.        
  71.         public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner)
  72.         {
  73.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  74.             DynamicMethod.PerformSecurityCheck(owner, ref stackMark, false);
  75.             Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, null, false);
  76.         }
  77.        
  78.         public DynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility)
  79.         {
  80.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  81.             DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility);
  82.             Init(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, null, skipVisibility);
  83.         }
  84.        
  85.         public DynamicMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility)
  86.         {
  87.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  88.             DynamicMethod.PerformSecurityCheck(owner, ref stackMark, skipVisibility);
  89.             Init(name, attributes, callingConvention, returnType, parameterTypes, owner, null, skipVisibility);
  90.         }
  91.        
  92.         // helpers for intialization
  93.        
  94.         private static void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention)
  95.         {
  96.             // only static public for method attributes
  97.             if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static)
  98.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
  99.             if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
  100.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
  101.            
  102.             // only standard or varargs supported
  103.             if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs)
  104.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
  105.            
  106.             // vararg is not supported at the moment
  107.             if (callingConvention == CallingConventions.VarArgs)
  108.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
  109.         }
  110.        
  111.         unsafe private void Init(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] signature, Type owner, Module m, bool skipVisibility)
  112.         {
  113.            
  114.             DynamicMethod.CheckConsistency(attributes, callingConvention);
  115.            
  116.             // check and store the signature
  117.             if (signature != null) {
  118.                 m_parameterTypes = new RuntimeType[signature.Length];
  119.                 for (int i = 0; i < signature.Length; i++) {
  120.                     if (signature[i] == null)
  121.                         throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
  122.                     m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType;
  123.                     if (m_parameterTypes[i] == null || m_parameterTypes[i] == typeof(void))
  124.                         throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
  125.                 }
  126.             }
  127.             else
  128.                 m_parameterTypes = new RuntimeType[0];
  129.            
  130.             // check and store the return value
  131.             m_returnType = (returnType == null) ? ((RuntimeType)typeof(void)) : (returnType.UnderlyingSystemType as RuntimeType);
  132.             if (m_returnType == null || m_returnType.IsByRef)
  133.                 throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType"));
  134.            
  135.             m_typeOwner = (owner != null) ? owner.UnderlyingSystemType as RuntimeType : null;
  136.             if (m_typeOwner != null)
  137.                 if (m_typeOwner.HasElementType || m_typeOwner.ContainsGenericParameters || m_typeOwner.IsGenericParameter || m_typeOwner.IsInterface)
  138.                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod"));
  139.            
  140.             m_module = (m != null) ? m.ModuleHandle : m_typeOwner.Module.ModuleHandle;
  141.            
  142.             // initialize remaining fields
  143.             m_ilGenerator = null;
  144.             m_fInitLocals = true;
  145.             m_method = new RuntimeMethodHandle(null);
  146.             m_skipVisibility = skipVisibility;
  147.            
  148.             if (name == null)
  149.                 throw new ArgumentNullException("name");
  150.             m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention);
  151.         }
  152.        
  153.         private static void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility)
  154.         {
  155.             unsafe {
  156.                 if (m == null)
  157.                     throw new ArgumentNullException("m");
  158.                
  159.                 // ask for ReflectionEmit permission always
  160.                 new ReflectionPermission(ReflectionPermissionFlag.ReflectionEmit).Demand();
  161.                 // ask for member access if skip visibility
  162.                 if (skipVisibility)
  163.                     new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
  164.                
  165.                 // ask for control evidence if outside of the caller assembly
  166.                 RuntimeTypeHandle callingType = ModuleHandle.GetCallerType(ref stackMark);
  167.                 if (!m.Assembly.AssemblyHandle.Equals(callingType.GetAssemblyHandle()))
  168.                     new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
  169.             }
  170.         }
  171.        
  172.         private static void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility)
  173.         {
  174.             unsafe {
  175.                 if (owner == null || ((owner = owner.UnderlyingSystemType as RuntimeType) == null))
  176.                     throw new ArgumentNullException("owner");
  177.                
  178.                 // ask for ReflectionEmit permission always
  179.                 new ReflectionPermission(ReflectionPermissionFlag.ReflectionEmit).Demand();
  180.                
  181.                 // get the type the call is coming from
  182.                 RuntimeTypeHandle callingType = ModuleHandle.GetCallerType(ref stackMark);
  183.                
  184.                 // ask for member access if skip visibility
  185.                 if (skipVisibility)
  186.                     new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
  187.                 else {
  188.                     // if the call is not coming from the same class ask for member access
  189.                     if (!callingType.Equals(owner.TypeHandle))
  190.                         new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
  191.                 }
  192.                
  193.                 // ask for control evidence if outside of the caller module
  194.                 if (!owner.Assembly.AssemblyHandle.Equals(callingType.GetAssemblyHandle()))
  195.                     new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
  196.             }
  197.         }
  198.        
  199.         //
  200.         // Delegate and method creation
  201.         //
  202.        
  203.         [System.Runtime.InteropServices.ComVisible(true)]
  204.         public Delegate CreateDelegate(Type delegateType)
  205.         {
  206.             MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, null, GetMethodDescriptor());
  207.             // stash this MethodInfo by brute force.
  208.             d.StoreDynamicMethod(GetMethodInfo());
  209.             // create a Multicast delegate to protect the delegate on invocation
  210.             object[] invocationList = new object[1] {d};
  211.             return d.NewMulticastDelegate(invocationList, invocationList.Length);
  212.         }
  213.        
  214.         [System.Runtime.InteropServices.ComVisible(true)]
  215.         public Delegate CreateDelegate(Type delegateType, object target)
  216.         {
  217.             MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegate(delegateType, target, GetMethodDescriptor());
  218.             // stash this MethodInfo by brute force.
  219.             d.StoreDynamicMethod(GetMethodInfo());
  220.             // create a Multicast delegate to protect the delegate on invocation
  221.             object[] invocationList = new object[1] {d};
  222.             return d.NewMulticastDelegate(invocationList, invocationList.Length);
  223.         }
  224.        
  225.         unsafe internal RuntimeMethodHandle GetMethodDescriptor()
  226.         {
  227.             if (m_method.IsNullHandle()) {
  228.                 lock (this) {
  229.                     if (m_method.IsNullHandle()) {
  230.                         if (m_DynamicILInfo != null)
  231.                             m_method = m_DynamicILInfo.GetCallableMethod(m_module.Value);
  232.                         else {
  233.                             if (m_ilGenerator == null || m_ilGenerator.m_length == 0)
  234.                                 throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody"), Name));
  235.                            
  236.                             m_method = m_ilGenerator.GetCallableMethod(m_module.Value);
  237.                         }
  238.                     }
  239.                 }
  240.             }
  241.             return m_method;
  242.         }
  243.        
  244.         //
  245.         // MethodInfo api. They mostly forward to RTDynamicMethod
  246.         //
  247.        
  248.         public override string ToString()
  249.         {
  250.             return m_dynMethod.ToString();
  251.         }
  252.        
  253.         public override string Name {
  254.             get { return m_dynMethod.Name; }
  255.         }
  256.        
  257.         public override Type DeclaringType {
  258.             get { return m_dynMethod.DeclaringType; }
  259.         }
  260.        
  261.         public override Type ReflectedType {
  262.             get { return m_dynMethod.ReflectedType; }
  263.         }
  264.        
  265.         internal override int MetadataTokenInternal {
  266.             get { return m_dynMethod.MetadataTokenInternal; }
  267.         }
  268.        
  269.         public override Module Module {
  270.             get { return m_dynMethod.Module; }
  271.         }
  272.        
  273.         // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits
  274.         public override RuntimeMethodHandle MethodHandle {
  275.             get {
  276.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  277.             }
  278.         }
  279.        
  280.         public override MethodAttributes Attributes {
  281.             get { return m_dynMethod.Attributes; }
  282.         }
  283.        
  284.         public override CallingConventions CallingConvention {
  285.             get { return m_dynMethod.CallingConvention; }
  286.         }
  287.        
  288.         public override MethodInfo GetBaseDefinition()
  289.         {
  290.             return this;
  291.         }
  292.        
  293.         public override ParameterInfo[] GetParameters()
  294.         {
  295.             return m_dynMethod.GetParameters();
  296.         }
  297.        
  298.         public override MethodImplAttributes GetMethodImplementationFlags()
  299.         {
  300.             return m_dynMethod.GetMethodImplementationFlags();
  301.         }
  302.        
  303.         public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
  304.         {
  305.             return m_dynMethod.Invoke(obj, invokeAttr, binder, parameters, culture);
  306.         }
  307.        
  308.         public override object[] GetCustomAttributes(Type attributeType, bool inherit)
  309.         {
  310.             return m_dynMethod.GetCustomAttributes(attributeType, inherit);
  311.         }
  312.        
  313.         public override object[] GetCustomAttributes(bool inherit)
  314.         {
  315.             return m_dynMethod.GetCustomAttributes(inherit);
  316.         }
  317.        
  318.         public override bool IsDefined(Type attributeType, bool inherit)
  319.         {
  320.             return m_dynMethod.IsDefined(attributeType, inherit);
  321.         }
  322.        
  323.         public override Type ReturnType {
  324.             get { return m_dynMethod.ReturnType; }
  325.         }
  326.        
  327.         public override ParameterInfo ReturnParameter {
  328.             get { return m_dynMethod.ReturnParameter; }
  329.         }
  330.        
  331.         public override ICustomAttributeProvider ReturnTypeCustomAttributes {
  332.             get { return m_dynMethod.ReturnTypeCustomAttributes; }
  333.         }
  334.        
  335.         internal override bool IsOverloaded {
  336.             get { return m_dynMethod.IsOverloaded; }
  337.         }
  338.        
  339.         //
  340.         // DynamicMethod specific methods
  341.         //
  342.        
  343.         public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string parameterName)
  344.         {
  345.             if (position < 0 || position > m_parameterTypes.Length)
  346.                 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
  347.             position--;
  348.             // it's 1 based. 0 is the return value
  349.             if (position >= 0) {
  350.                 ParameterInfo[] parameters = m_dynMethod.LoadParameters();
  351.                 parameters[position].SetName(parameterName);
  352.                 parameters[position].SetAttributes(attributes);
  353.             }
  354.             return null;
  355.         }
  356.        
  357.         public DynamicILInfo GetDynamicILInfo()
  358.         {
  359.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  360.            
  361.             if (m_DynamicILInfo != null)
  362.                 return m_DynamicILInfo;
  363.            
  364.             return GetDynamicILInfo(new DynamicScope());
  365.         }
  366.        
  367.         internal DynamicILInfo GetDynamicILInfo(DynamicScope scope)
  368.         {
  369.             if (m_DynamicILInfo == null) {
  370.                 byte[] methodSignature = SignatureHelper.GetMethodSigHelper(null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true);
  371.                 m_DynamicILInfo = new DynamicILInfo(scope, this, methodSignature);
  372.             }
  373.            
  374.             return m_DynamicILInfo;
  375.         }
  376.        
  377.         public ILGenerator GetILGenerator()
  378.         {
  379.             return GetILGenerator(64);
  380.         }
  381.        
  382.         public ILGenerator GetILGenerator(int streamSize)
  383.         {
  384.             if (m_ilGenerator == null) {
  385.                 byte[] methodSignature = SignatureHelper.GetMethodSigHelper(null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true);
  386.                 m_ilGenerator = new DynamicILGenerator(this, methodSignature, streamSize);
  387.             }
  388.             return m_ilGenerator;
  389.         }
  390.        
  391.         public bool InitLocals {
  392.             get { return m_fInitLocals; }
  393.             set { m_fInitLocals = value; }
  394.         }
  395.        
  396.         //
  397.         // Internal API
  398.         //
  399.        
  400.         internal MethodInfo GetMethodInfo()
  401.         {
  402.             return m_dynMethod;
  403.         }
  404.        
  405.         static internal DynamicMethod AsDynamicMethod(MethodBase meth)
  406.         {
  407.             DynamicMethod dynmeth = meth as DynamicMethod;
  408.             if (dynmeth == null) {
  409.                 RTDynamicMethod rtdynmeth = meth as RTDynamicMethod;
  410.                 if (rtdynmeth != null) {
  411.                     dynmeth = rtdynmeth.m_owner;
  412.                 }
  413.             }
  414.             return dynmeth;
  415.         }
  416.        
  417.         //////////////////////////////////////////////////////////////////////////////////////////////
  418.         // RTDynamicMethod
  419.         //
  420.         // this is actually the real runtime instance of a method info that gets used for invocation
  421.         // We need this so we never leak the DynamicMethod out via an exception.
  422.         // This way the DynamicMethod creator is the only responsible for DynamicMethod access
  423.         //
  424.         internal class RTDynamicMethod : MethodInfo
  425.         {
  426.            
  427.             internal DynamicMethod m_owner;
  428.             ParameterInfo[] m_parameters;
  429.             string m_name;
  430.             MethodAttributes m_attributes;
  431.             CallingConventions m_callingConvention;
  432.            
  433.             //
  434.             // ctors
  435.             //
  436.             private RTDynamicMethod()
  437.             {
  438.             }
  439.            
  440.             internal RTDynamicMethod(DynamicMethod owner, string name, MethodAttributes attributes, CallingConventions callingConvention)
  441.             {
  442.                 m_owner = owner;
  443.                 m_name = name;
  444.                 m_attributes = attributes;
  445.                 m_callingConvention = callingConvention;
  446.             }
  447.            
  448.             //
  449.             // MethodInfo api
  450.             //
  451.             public override string ToString()
  452.             {
  453.                 return ReturnType.SigToString() + " " + RuntimeMethodInfo.ConstructName(this);
  454.             }
  455.            
  456.             public override string Name {
  457.                 get { return m_name; }
  458.             }
  459.            
  460.             public override Type DeclaringType {
  461.                 get { return null; }
  462.             }
  463.            
  464.             public override Type ReflectedType {
  465.                 get { return null; }
  466.             }
  467.            
  468.             internal override int MetadataTokenInternal {
  469.                 get { return 0; }
  470.             }
  471.            
  472.             public override Module Module {
  473.                 get { return m_owner.m_module.GetModule(); }
  474.             }
  475.            
  476.             public override RuntimeMethodHandle MethodHandle {
  477.                 get {
  478.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
  479.                 }
  480.             }
  481.            
  482.             public override MethodAttributes Attributes {
  483.                 get { return m_attributes; }
  484.             }
  485.            
  486.             public override CallingConventions CallingConvention {
  487.                 get { return m_callingConvention; }
  488.             }
  489.            
  490.             public override MethodInfo GetBaseDefinition()
  491.             {
  492.                 return this;
  493.             }
  494.            
  495.             public override ParameterInfo[] GetParameters()
  496.             {
  497.                 ParameterInfo[] privateParameters = LoadParameters();
  498.                 ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length];
  499.                 Array.Copy(privateParameters, parameters, privateParameters.Length);
  500.                 return parameters;
  501.             }
  502.            
  503.             public override MethodImplAttributes GetMethodImplementationFlags()
  504.             {
  505.                 return MethodImplAttributes.IL | MethodImplAttributes.NoInlining;
  506.             }
  507.            
  508.             public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
  509.             {
  510.                 // always ask for MemberAccess
  511.                 new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
  512.                
  513.                 RuntimeMethodHandle method = m_owner.GetMethodDescriptor();
  514.                 // ignore obj since it's a static method
  515.                
  516.                 if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
  517.                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg"));
  518.                
  519.                 // create a signature object
  520.                 RuntimeTypeHandle[] argumentHandles = new RuntimeTypeHandle[m_owner.m_parameterTypes.Length];
  521.                 for (int i = 0; i < argumentHandles.Length; i++)
  522.                     argumentHandles[i] = m_owner.m_parameterTypes[i].TypeHandle;
  523.                 Signature sig = new Signature(method, argumentHandles, m_owner.m_returnType.TypeHandle, m_callingConvention);
  524.                
  525.                
  526.                 // verify arguments
  527.                 int formalCount = sig.Arguments.Length;
  528.                 int actualCount = (parameters != null) ? parameters.Length : 0;
  529.                 if (formalCount != actualCount)
  530.                     throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
  531.                
  532.                 // if we are here we passed all the previous checks. Time to look at the arguments
  533.                 object retValue = null;
  534.                 if (actualCount > 0) {
  535.                     object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
  536.                     retValue = method.InvokeMethodFast(null, arguments, sig, m_attributes, RuntimeTypeHandle.EmptyHandle);
  537.                     // copy out. This should be made only if ByRef are present.
  538.                     for (int index = 0; index < actualCount; index++)
  539.                         parameters[index] = arguments[index];
  540.                 }
  541.                 else {
  542.                     retValue = method.InvokeMethodFast(null, null, sig, m_attributes, RuntimeTypeHandle.EmptyHandle);
  543.                 }
  544.                
  545.                 GC.KeepAlive(this);
  546.                 return retValue;
  547.             }
  548.            
  549.             public override object[] GetCustomAttributes(Type attributeType, bool inherit)
  550.             {
  551.                 if (attributeType == null)
  552.                     throw new ArgumentNullException("attributeType");
  553.                
  554.                 if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
  555.                     return new object[] {new MethodImplAttribute(GetMethodImplementationFlags())};
  556.                 else
  557.                     return new object[0];
  558.             }
  559.            
  560.             public override object[] GetCustomAttributes(bool inherit)
  561.             {
  562.                 // support for MethodImplAttribute PCA
  563.                 return new object[] {new MethodImplAttribute(GetMethodImplementationFlags())};
  564.             }
  565.            
  566.             public override bool IsDefined(Type attributeType, bool inherit)
  567.             {
  568.                 if (attributeType == null)
  569.                     throw new ArgumentNullException("attributeType");
  570.                
  571.                 if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
  572.                     return true;
  573.                 else
  574.                     return false;
  575.             }
  576.            
  577.             internal override Type GetReturnType()
  578.             {
  579.                 return m_owner.m_returnType;
  580.             }
  581.            
  582.             public override ParameterInfo ReturnParameter {
  583.                 get { return null; }
  584.             }
  585.            
  586.             public override ICustomAttributeProvider ReturnTypeCustomAttributes {
  587.                 get { return GetEmptyCAHolder(); }
  588.             }
  589.            
  590.             internal override bool IsOverloaded {
  591.                 get { return false; }
  592.             }
  593.            
  594.             //
  595.             // private implementation
  596.             //
  597.            
  598.             internal ParameterInfo[] LoadParameters()
  599.             {
  600.                 if (m_parameters == null) {
  601.                     RuntimeType[] parameterTypes = m_owner.m_parameterTypes;
  602.                     ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length];
  603.                     for (int i = 0; i < parameterTypes.Length; i++)
  604.                         parameters[i] = new ParameterInfo(this, null, parameterTypes[i], i);
  605.                     if (m_parameters == null)
  606.                         // should we interlockexchange?
  607.                         m_parameters = parameters;
  608.                 }
  609.                 return m_parameters;
  610.             }
  611.            
  612.             // private implementation of CA for the return type
  613.             private ICustomAttributeProvider GetEmptyCAHolder()
  614.             {
  615.                 return new EmptyCAHolder();
  616.             }
  617.            
  618.             ///////////////////////////////////////////////////
  619.             // EmptyCAHolder
  620.             private class EmptyCAHolder : ICustomAttributeProvider
  621.             {
  622.                 internal EmptyCAHolder()
  623.                 {
  624.                 }
  625.                
  626.                 object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit)
  627.                 {
  628.                     return new object[0];
  629.                 }
  630.                
  631.                 object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit)
  632.                 {
  633.                     return new object[0];
  634.                 }
  635.                
  636.                 bool ICustomAttributeProvider.IsDefined(Type attributeType, bool inherit)
  637.                 {
  638.                     return false;
  639.                 }
  640.             }
  641.            
  642.         }
  643.        
  644.     }
  645.    
  646. }

Developer Fusion