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

  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.Text;
  18.     using System;
  19.     using CultureInfo = System.Globalization.CultureInfo;
  20.     using System.Diagnostics.SymbolStore;
  21.     using System.Reflection;
  22.     using System.Security;
  23.     using System.Collections;
  24.     using System.Security.Permissions;
  25.     using System.Runtime.InteropServices;
  26.    
  27.     [HostProtection(MayLeakOnAbort = true)]
  28.     [ClassInterface(ClassInterfaceType.None)]
  29.     [ComDefaultInterface(typeof(_MethodBuilder))]
  30.     [System.Runtime.InteropServices.ComVisible(true)]
  31.     public sealed class MethodBuilder : MethodInfo, _MethodBuilder
  32.     {
  33.         #region Private Data Members
  34.         // Identity
  35.         internal string m_strName;
  36.         // The name of the method
  37.         private MethodToken m_tkMethod;
  38.         // The token of this method
  39.         internal Module m_module;
  40.         internal TypeBuilder m_containingType;
  41.         private MethodBuilder m_link;
  42.        
  43.         // IL
  44.         private int[] m_RVAFixups;
  45.         // The location of all RVA fixups. Primarily used for Strings.
  46.         private int[] m_mdMethodFixups;
  47.         // The location of all of the token fixups.
  48.         private SignatureHelper m_localSignature;
  49.         internal LocalSymInfo m_localSymInfo;
  50.         // keep track debugging local information
  51.         internal ILGenerator m_ilGenerator;
  52.         private byte[] m_ubBody;
  53.         // The IL for the method
  54.         private int m_numExceptions;
  55.         // The number of exceptions. Each try-catch tuple is a separate exception.
  56.         private __ExceptionInstance[] m_exceptions;
  57.         //The instance of each exception.
  58.         // Flags
  59.         internal bool m_bIsBaked;
  60.         private bool m_bIsGlobalMethod;
  61.         private bool m_fInitLocals;
  62.         // indicating if the method stack frame will be zero initialized or not.
  63.         // Attributes
  64.         private MethodAttributes m_iAttributes;
  65.         private CallingConventions m_callingConvention;
  66.         private MethodImplAttributes m_dwMethodImplFlags;
  67.        
  68.         // Parameters
  69.         private SignatureHelper m_signature;
  70.         internal Type[] m_parameterTypes;
  71.         private ParameterBuilder m_retParam;
  72.         internal Type m_returnType;
  73.         private Type[] m_returnTypeRequiredCustomModifiers;
  74.         private Type[] m_returnTypeOptionalCustomModifiers;
  75.         private Type[][] m_parameterTypeRequiredCustomModifiers;
  76.         private Type[][] m_parameterTypeOptionalCustomModifiers;
  77.        
  78.         // Generics
  79.         private GenericTypeParameterBuilder[] m_inst;
  80.         private bool m_bIsGenMethDef;
  81.         #endregion
  82.        
  83.         #region Constructor
  84.         internal MethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module mod, TypeBuilder type, bool bIsGlobalMethod)
  85.         {
  86.             Init(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, mod,
  87.             type, bIsGlobalMethod);
  88.         }
  89.        
  90.         internal MethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, Module mod,
  91.         TypeBuilder type, bool bIsGlobalMethod)
  92.         {
  93.             Init(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, mod,
  94.             type, bIsGlobalMethod);
  95.         }
  96.        
  97.         private void Init(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, Module mod,
  98.         TypeBuilder type, bool bIsGlobalMethod)
  99.         {
  100.             if (name == null)
  101.                 throw new ArgumentNullException("name");
  102.            
  103.             if (name.Length == 0)
  104.                 throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
  105.            
  106.             if (name[0] == '\0')
  107.                 throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
  108.            
  109.             if (mod == null)
  110.                 throw new ArgumentNullException("mod");
  111.            
  112.             if (parameterTypes != null) {
  113.                 foreach (Type t in parameterTypes) {
  114.                     if (t == null)
  115.                         throw new ArgumentNullException("parameterTypes");
  116.                 }
  117.             }
  118.            
  119.             m_link = type.m_currentMethod;
  120.             type.m_currentMethod = this;
  121.             m_strName = name;
  122.             m_module = mod;
  123.             m_containingType = type;
  124.             m_localSignature = SignatureHelper.GetLocalVarSigHelper(mod);
  125.            
  126.             //
  127.             //if (returnType == null)
  128.             //{
  129.             // m_returnType = typeof(void);
  130.             //}
  131.             //else
  132.             {
  133.                 m_returnType = returnType;
  134.             }
  135.            
  136.             if ((attributes & MethodAttributes.Static) == 0) {
  137.                 // turn on the has this calling convention
  138.                 callingConvention = callingConvention | CallingConventions.HasThis;
  139.             }
  140.             else if ((attributes & MethodAttributes.Virtual) != 0) {
  141.                 // A method can't be both static and virtual
  142.                 throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual"));
  143.             }
  144.            
  145.             if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName) {
  146.                 if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface) {
  147.                     // methods on interface have to be abstract + virtual except special name methods such as type initializer
  148.                     if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != (MethodAttributes.Abstract | MethodAttributes.Virtual) && (attributes & MethodAttributes.Static) == 0)
  149.                         throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
  150.                 }
  151.             }
  152.            
  153.             m_callingConvention = callingConvention;
  154.            
  155.             if (parameterTypes != null) {
  156.                 m_parameterTypes = new Type[parameterTypes.Length];
  157.                 Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
  158.             }
  159.             else {
  160.                 m_parameterTypes = null;
  161.             }
  162.            
  163.             m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
  164.             m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
  165.             m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
  166.             m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
  167.            
  168.             // m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
  169.             // returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
  170.             // parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
  171.            
  172.             m_iAttributes = attributes;
  173.             m_bIsGlobalMethod = bIsGlobalMethod;
  174.             m_bIsBaked = false;
  175.             m_fInitLocals = true;
  176.            
  177.             m_localSymInfo = new LocalSymInfo();
  178.             m_ubBody = null;
  179.             m_ilGenerator = null;
  180.            
  181.             // Default is managed IL. Manged IL has bit flag 0x0020 set off
  182.             m_dwMethodImplFlags = MethodImplAttributes.IL;
  183.            
  184.             //int i = MetadataTokenInternal;
  185.         }
  186.        
  187.         #endregion
  188.        
  189.         #region Internal Members
  190.         internal void CheckContext(params Type[][] typess)
  191.         {
  192.             ((AssemblyBuilder)Module.Assembly).CheckContext(typess);
  193.         }
  194.         internal void CheckContext(params Type[] types)
  195.         {
  196.             ((AssemblyBuilder)Module.Assembly).CheckContext(types);
  197.         }
  198.        
  199.         internal void CreateMethodBodyHelper(ILGenerator il)
  200.         {
  201.             // Sets the IL of the method. An ILGenerator is passed as an argument and the method
  202.             // queries this instance to get all of the information which it needs.
  203.            
  204.             __ExceptionInfo[] excp;
  205.             int counter = 0;
  206.             int[] filterAddrs;
  207.             int[] catchAddrs;
  208.             int[] catchEndAddrs;
  209.             Type[] catchClass;
  210.             int[] type;
  211.             int numCatch;
  212.             int start;
  213.             int end;
  214.             ModuleBuilder dynMod = (ModuleBuilder)m_module;
  215.            
  216.             m_containingType.ThrowIfCreated();
  217.            
  218.             if (m_bIsBaked) {
  219.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody"));
  220.             }
  221.            
  222.             if (il == null) {
  223.                 throw new ArgumentNullException("il");
  224.             }
  225.            
  226.             if (il.m_methodBuilder != this && il.m_methodBuilder != null) {
  227.                 // you don't need to call CreateMethodBody when you get your ILGenerator
  228.                 // through MethodBuilder::GetILGenerator.
  229.                 //
  230.                
  231.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
  232.             }
  233.            
  234.             ThrowIfShouldNotHaveBody();
  235.            
  236.             if (il.m_ScopeTree.m_iOpenScopeCount != 0) {
  237.                 // There are still unclosed local scope
  238.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope"));
  239.             }
  240.            
  241.            
  242.             m_ubBody = il.BakeByteArray();
  243.            
  244.             m_RVAFixups = il.GetRVAFixups();
  245.             m_mdMethodFixups = il.GetTokenFixups();
  246.            
  247.             //Okay, now the fun part. Calculate all of the exceptions.
  248.             excp = il.GetExceptions();
  249.             m_numExceptions = CalculateNumberOfExceptions(excp);
  250.             if (m_numExceptions > 0) {
  251.                
  252.                 m_exceptions = new __ExceptionInstance[m_numExceptions];
  253.                
  254.                 for (int i = 0; i < excp.Length; i++) {
  255.                     filterAddrs = excp[i].GetFilterAddresses();
  256.                     catchAddrs = excp[i].GetCatchAddresses();
  257.                     catchEndAddrs = excp[i].GetCatchEndAddresses();
  258.                     catchClass = excp[i].GetCatchClass();
  259.                    
  260.                    
  261.                     // track the reference of the catch class
  262.                     for (int j = 0; j < catchClass.Length; j++) {
  263.                         if (catchClass[j] != null)
  264.                             dynMod.GetTypeToken(catchClass[j]);
  265.                     }
  266.                    
  267.                     numCatch = excp[i].GetNumberOfCatches();
  268.                     start = excp[i].GetStartAddress();
  269.                     end = excp[i].GetEndAddress();
  270.                     type = excp[i].GetExceptionTypes();
  271.                     for (int j = 0; j < numCatch; j++) {
  272.                         int tkExceptionClass = 0;
  273.                         if (catchClass[j] != null)
  274.                             tkExceptionClass = dynMod.GetTypeToken(catchClass[j]).Token;
  275.                         switch (type[j]) {
  276.                             case __ExceptionInfo.None:
  277.                             case __ExceptionInfo.Fault:
  278.                             case __ExceptionInfo.Filter:
  279.                                 m_exceptions[counter++] = new __ExceptionInstance(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
  280.                                 break;
  281.                             case __ExceptionInfo.Finally:
  282.                                
  283.                                 m_exceptions[counter++] = new __ExceptionInstance(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass);
  284.                                 break;
  285.                         }
  286.                     }
  287.                    
  288.                 }
  289.             }
  290.            
  291.            
  292.             m_bIsBaked = true;
  293.            
  294.             if (dynMod.GetSymWriter() != null) {
  295.                
  296.                 // set the debugging information such as scope and line number
  297.                 // if it is in a debug module
  298.                 //
  299.                 SymbolToken tk = new SymbolToken(MetadataTokenInternal);
  300.                 ISymbolWriter symWriter = dynMod.GetSymWriter();
  301.                
  302.                 // call OpenMethod to make this method the current method
  303.                 symWriter.OpenMethod(tk);
  304.                
  305.                 // call OpenScope because OpenMethod no longer implicitly creating
  306.                 // the top-levelsmethod scope
  307.                 //
  308.                 symWriter.OpenScope(0);
  309.                
  310.                 if (m_symCustomAttrs != null) {
  311.                     foreach (SymCustomAttr symCustomAttr in m_symCustomAttrs)
  312.                         dynMod.GetSymWriter().SetSymAttribute(new SymbolToken(MetadataTokenInternal), symCustomAttr.m_name, symCustomAttr.m_data);
  313.                 }
  314.                
  315.                 if (m_localSymInfo != null)
  316.                     m_localSymInfo.EmitLocalSymInfo(symWriter);
  317.                 il.m_ScopeTree.EmitScopeTree(symWriter);
  318.                 il.m_LineNumberInfo.EmitLineNumberInfo(symWriter);
  319.                 symWriter.CloseScope(il.m_length);
  320.                 symWriter.CloseMethod();
  321.             }
  322.         }
  323.        
  324.         internal override Type[] GetParameterTypes()
  325.         {
  326.             if (m_parameterTypes == null)
  327.                 m_parameterTypes = new Type[0];
  328.            
  329.             return m_parameterTypes;
  330.         }
  331.        
  332.         internal void SetToken(MethodToken token)
  333.         {
  334.             m_tkMethod = token;
  335.         }
  336.        
  337.         internal byte[] GetBody()
  338.         {
  339.             // Returns the il bytes of this method.
  340.             // This il is not valid until somebody has called BakeByteArray
  341.             return m_ubBody;
  342.         }
  343.        
  344.         internal int[] GetTokenFixups()
  345.         {
  346.             return m_mdMethodFixups;
  347.         }
  348.        
  349.         internal int[] GetRVAFixups()
  350.         {
  351.             return m_RVAFixups;
  352.         }
  353.        
  354.         internal SignatureHelper GetMethodSignature()
  355.         {
  356.             if (m_parameterTypes == null)
  357.                 m_parameterTypes = new Type[0];
  358.            
  359.             m_signature = SignatureHelper.GetMethodSigHelper(m_module, m_callingConvention, m_inst != null ? m_inst.Length : 0, m_returnType == null ? typeof(void) : m_returnType, m_returnTypeRequiredCustomModifiers, m_returnTypeOptionalCustomModifiers, m_parameterTypes, m_parameterTypeRequiredCustomModifiers, m_parameterTypeOptionalCustomModifiers);
  360.            
  361.             return m_signature;
  362.         }
  363.        
  364.         internal SignatureHelper GetLocalsSignature()
  365.         {
  366.             if (m_ilGenerator != null) {
  367.                 if (m_ilGenerator.m_localCount != 0) {
  368.                     // If user is using ILGenerator::DeclareLocal, then get local signaturefrom there.
  369.                     return m_ilGenerator.m_localSignature;
  370.                 }
  371.             }
  372.            
  373.             return m_localSignature;
  374.         }
  375.        
  376.         internal int GetNumberOfExceptions()
  377.         {
  378.             return m_numExceptions;
  379.         }
  380.        
  381.         internal __ExceptionInstance[] GetExceptionInstances()
  382.         {
  383.             return m_exceptions;
  384.         }
  385.        
  386.         internal int CalculateNumberOfExceptions(__ExceptionInfo[] excp)
  387.         {
  388.             int num = 0;
  389.            
  390.             if (excp == null) {
  391.                 return 0;
  392.             }
  393.            
  394.             for (int i = 0; i < excp.Length; i++) {
  395.                 num += excp[i].GetNumberOfCatches();
  396.             }
  397.            
  398.             return num;
  399.         }
  400.        
  401.         internal bool IsTypeCreated()
  402.         {
  403.             return (m_containingType != null && m_containingType.m_hasBeenCreated);
  404.         }
  405.        
  406.         internal TypeBuilder GetTypeBuilder()
  407.         {
  408.             return m_containingType;
  409.         }
  410.         #endregion
  411.        
  412.         #region Object Overrides
  413.         public override bool Equals(object obj)
  414.         {
  415.             if (!(obj is MethodBuilder)) {
  416.                 return false;
  417.             }
  418.             if (!(this.m_strName.Equals(((MethodBuilder)obj).m_strName))) {
  419.                 return false;
  420.             }
  421.            
  422.             if (m_iAttributes != (((MethodBuilder)obj).m_iAttributes)) {
  423.                 return false;
  424.             }
  425.            
  426.             SignatureHelper thatSig = ((MethodBuilder)obj).GetMethodSignature();
  427.             if (thatSig.Equals(GetMethodSignature())) {
  428.                 return true;
  429.             }
  430.             return false;
  431.         }
  432.        
  433.         public override int GetHashCode()
  434.         {
  435.             return this.m_strName.GetHashCode();
  436.         }
  437.        
  438.         public override string ToString()
  439.         {
  440.             StringBuilder sb = new StringBuilder(1000);
  441.             sb.Append("Name: " + m_strName + " " + Environment.NewLine);
  442.             sb.Append("Attributes: " + (int)m_iAttributes + Environment.NewLine);
  443.             sb.Append("Method Signature: " + GetMethodSignature() + Environment.NewLine);
  444.            
  445.             sb.Append(Environment.NewLine);
  446.             return sb.ToString();
  447.         }
  448.        
  449.         #endregion
  450.        
  451.         #region MemberInfo Overrides
  452.         public override string Name {
  453.             get { return m_strName; }
  454.         }
  455.        
  456.         internal override int MetadataTokenInternal {
  457.             get { return GetToken().Token; }
  458.         }
  459.        
  460.         public override Module Module {
  461.             get { return m_containingType.Module; }
  462.         }
  463.        
  464.         public override Type DeclaringType {
  465.             get {
  466.                 if (m_containingType.m_isHiddenGlobalType == true)
  467.                     return null;
  468.                 return m_containingType;
  469.             }
  470.         }
  471.        
  472.         public override ICustomAttributeProvider ReturnTypeCustomAttributes {
  473.             get { return null; }
  474.         }
  475.        
  476.         public override Type ReflectedType {
  477.             get {
  478.                 if (m_containingType.m_isHiddenGlobalType == true)
  479.                     return null;
  480.                 return m_containingType;
  481.             }
  482.         }
  483.        
  484.         #endregion
  485.        
  486.         #region MethodBase Overrides
  487.         public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
  488.         {
  489.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  490.         }
  491.        
  492.         public override MethodImplAttributes GetMethodImplementationFlags()
  493.         {
  494.             return m_dwMethodImplFlags;
  495.         }
  496.        
  497.         public override MethodAttributes Attributes {
  498.             get { return m_iAttributes; }
  499.         }
  500.        
  501.         public override CallingConventions CallingConvention {
  502.             get { return m_callingConvention; }
  503.         }
  504.        
  505.         public override RuntimeMethodHandle MethodHandle {
  506.             get {
  507.                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  508.             }
  509.         }
  510.        
  511.         #endregion
  512.        
  513.         #region MethodInfo Overrides
  514.         public override MethodInfo GetBaseDefinition()
  515.         {
  516.             return this;
  517.         }
  518.        
  519.         internal override Type GetReturnType()
  520.         {
  521.             return m_returnType;
  522.         }
  523.        
  524.         public override ParameterInfo[] GetParameters()
  525.         {
  526.             if (!m_bIsBaked)
  527.                 throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
  528.            
  529.             Type rti = m_containingType.m_runtimeType;
  530.             MethodInfo rmi = rti.GetMethod(m_strName, m_parameterTypes);
  531.            
  532.             return rmi.GetParameters();
  533.         }
  534.        
  535.         public override ParameterInfo ReturnParameter {
  536.             get {
  537.                 if (!m_bIsBaked)
  538.                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
  539.                
  540.                 Type rti = m_containingType.m_runtimeType;
  541.                 MethodInfo rmi = rti.GetMethod(m_strName, m_parameterTypes);
  542.                
  543.                 return rmi.ReturnParameter;
  544.             }
  545.         }
  546.         #endregion
  547.        
  548.         #region ICustomAttributeProvider Implementation
  549.         public override object[] GetCustomAttributes(bool inherit)
  550.         {
  551.            
  552.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  553.         }
  554.        
  555.         public override object[] GetCustomAttributes(Type attributeType, bool inherit)
  556.         {
  557.            
  558.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  559.         }
  560.        
  561.         public override bool IsDefined(Type attributeType, bool inherit)
  562.         {
  563.            
  564.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
  565.         }
  566.        
  567.         #endregion
  568.        
  569.         #region Generic Members
  570.         public override bool IsGenericMethodDefinition {
  571.             get { return m_bIsGenMethDef; }
  572.         }
  573.        
  574.         public override bool ContainsGenericParameters {
  575.             get {
  576.                 throw new NotSupportedException();
  577.             }
  578.         }
  579.        
  580.         public override MethodInfo GetGenericMethodDefinition()
  581.         {
  582.             if (!IsGenericMethod)
  583.                 throw new InvalidOperationException();
  584.             return this;
  585.         }
  586.        
  587.         public override bool IsGenericMethod {
  588.             get { return m_inst != null; }
  589.         }
  590.        
  591.         public override Type[] GetGenericArguments()
  592.         {
  593.             return m_inst;
  594.         }
  595.        
  596.         public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
  597.         {
  598.             return new MethodBuilderInstantiation(this, typeArguments);
  599.         }
  600.        
  601.        
  602.         public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
  603.         {
  604.             if (m_inst != null)
  605.                 throw new InvalidOperationException();
  606.            
  607.             if (names == null)
  608.                 throw new ArgumentNullException("names");
  609.            
  610.             for (int i = 0; i < names.Length; i++)
  611.                 if (names[i] == null)
  612.                     throw new ArgumentNullException("names");
  613.            
  614.             if (m_tkMethod.Token != 0)
  615.                 throw new InvalidOperationException();
  616.            
  617.             if (names.Length == 0)
  618.                 throw new ArgumentException();
  619.            
  620.             m_bIsGenMethDef = true;
  621.             m_inst = new GenericTypeParameterBuilder[names.Length];
  622.             for (int i = 0; i < names.Length; i++)
  623.                 m_inst[i] = new GenericTypeParameterBuilder(new TypeBuilder(names[i], i, this));
  624.            
  625.             return m_inst;
  626.         }
  627.        
  628.         internal void ThrowIfGeneric()
  629.         {
  630.             if (IsGenericMethod && !IsGenericMethodDefinition)
  631.                 throw new InvalidOperationException();
  632.         }
  633.         #endregion
  634.        
  635.         #region Public Members
  636.         public MethodToken GetToken()
  637.         {
  638.             if (m_tkMethod.Token == 0) {
  639.                 if (m_link != null)
  640.                     m_link.GetToken();
  641.                
  642.                 int sigLength;
  643.                 byte[] sigBytes = GetMethodSignature().InternalGetSignature(out sigLength);
  644.                
  645.                 m_tkMethod = new MethodToken(TypeBuilder.InternalDefineMethod(m_containingType.MetadataTokenInternal, m_strName, sigBytes, sigLength, Attributes, m_module));
  646.                
  647.                 if (m_inst != null)
  648.                     foreach (GenericTypeParameterBuilder tb in m_inst)
  649.                         if (!tb.m_type.IsCreated())
  650.                             tb.m_type.CreateType();
  651.                
  652.                 TypeBuilder.InternalSetMethodImpl(m_module, MetadataTokenInternal, m_dwMethodImplFlags);
  653.             }
  654.            
  655.             return m_tkMethod;
  656.         }
  657.        
  658.         public void SetParameters(params Type[] parameterTypes)
  659.         {
  660.             CheckContext(parameterTypes);
  661.             SetSignature(null, null, null, parameterTypes, null, null);
  662.         }
  663.        
  664.         public void SetReturnType(Type returnType)
  665.         {
  666.             CheckContext(returnType);
  667.             SetSignature(returnType, null, null, null, null, null);
  668.         }
  669.        
  670.         public void SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
  671.         {
  672.             CheckContext(returnType);
  673.             CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes);
  674.             CheckContext(parameterTypeRequiredCustomModifiers);
  675.             CheckContext(parameterTypeOptionalCustomModifiers);
  676.            
  677.             ThrowIfGeneric();
  678.            
  679.             if (returnType != null) {
  680.                 m_returnType = returnType;
  681.             }
  682.            
  683.             if (parameterTypes != null) {
  684.                 m_parameterTypes = new Type[parameterTypes.Length];
  685.                 Array.Copy(parameterTypes, m_parameterTypes, parameterTypes.Length);
  686.             }
  687.            
  688.             m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
  689.             m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers;
  690.             m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
  691.             m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
  692.         }
  693.        
  694.        
  695.         public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string strParamName)
  696.         {
  697.             ThrowIfGeneric();
  698.             m_containingType.ThrowIfCreated();
  699.            
  700.             if (position < 0)
  701.                 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
  702.            
  703.             if (position > 0 && (m_parameterTypes == null || position > m_parameterTypes.Length))
  704.                 throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
  705.            
  706.             attributes = attributes & ~ParameterAttributes.ReservedMask;
  707.             return new ParameterBuilder(this, position, attributes, strParamName);
  708.         }
  709.        
  710.         [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
  711.         public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
  712.         {
  713.             ThrowIfGeneric();
  714.            
  715.             // set Marshal info for the return type
  716.            
  717.             m_containingType.ThrowIfCreated();
  718.            
  719.             if (m_retParam == null) {
  720.                 m_retParam = new ParameterBuilder(this, 0, 0, null);
  721.             }
  722.            
  723.             m_retParam.SetMarshal(unmanagedMarshal);
  724.         }
  725.        
  726.         private ArrayList m_symCustomAttrs;
  727.         private struct SymCustomAttr
  728.         {
  729.             public SymCustomAttr(string name, byte[] data)
  730.             {
  731.                 m_name = name;
  732.                 m_data = data;
  733.             }
  734.             public string m_name;
  735.             public byte[] m_data;
  736.         }
  737.        
  738.         public void SetSymCustomAttribute(string name, byte[] data)
  739.         {
  740.             ThrowIfGeneric();
  741.            
  742.             // This is different from CustomAttribute. This is stored into the SymWriter.
  743.             m_containingType.ThrowIfCreated();
  744.            
  745.             ModuleBuilder dynMod = (ModuleBuilder)m_module;
  746.             if (dynMod.GetSymWriter() == null) {
  747.                 // Cannot SetSymCustomAttribute when it is not a debug module
  748.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
  749.             }
  750.            
  751.             if (m_symCustomAttrs == null)
  752.                 m_symCustomAttrs = new ArrayList();
  753.            
  754.             m_symCustomAttrs.Add(new SymCustomAttr(name, data));
  755.         }
  756.        
  757.         public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
  758.         {
  759.             ThrowIfGeneric();
  760.            
  761.             if (pset == null)
  762.                 throw new ArgumentNullException("pset");
  763.            
  764.             if (!Enum.IsDefined(typeof(SecurityAction), action) || action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional || action == SecurityAction.RequestRefuse)
  765.                 throw new ArgumentOutOfRangeException("action");
  766.            
  767.             // cannot declarative security after type is created
  768.             m_containingType.ThrowIfCreated();
  769.            
  770.             // Translate permission set into serialized format (uses standard binary serialization format).
  771.             byte[] blob = null;
  772.             if (!pset.IsEmpty())
  773.                 blob = pset.EncodeXml();
  774.            
  775.             // Write the blob into the metadata.
  776.             TypeBuilder.InternalAddDeclarativeSecurity(m_module, MetadataTokenInternal, action, blob);
  777.         }
  778.        
  779.         public void CreateMethodBody(byte[] il, int count)
  780.         {
  781.             ThrowIfGeneric();
  782.            
  783.             // Note that when user calls this function, there are a few information that client is
  784.             // not able to supply: local signature, exception handlers, max stack size, a list of Token fixup, a list of RVA fixup
  785.            
  786.             if (m_bIsBaked) {
  787.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
  788.             }
  789.            
  790.             m_containingType.ThrowIfCreated();
  791.            
  792.             if (il != null && (count < 0 || count > il.Length))
  793.                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
  794.             if (il == null) {
  795.                 m_ubBody = null;
  796.                 return;
  797.             }
  798.             m_ubBody = new byte[count];
  799.             Array.Copy(il, m_ubBody, count);
  800.             m_bIsBaked = true;
  801.         }
  802.        
  803.         public void SetImplementationFlags(MethodImplAttributes attributes)
  804.         {
  805.             ThrowIfGeneric();
  806.            
  807.             m_containingType.ThrowIfCreated();
  808.            
  809.             m_dwMethodImplFlags = attributes;
  810.            
  811.             m_canBeRuntimeImpl = true;
  812.            
  813.             TypeBuilder.InternalSetMethodImpl(m_module, MetadataTokenInternal, attributes);
  814.         }
  815.        
  816.         public ILGenerator GetILGenerator()
  817.         {
  818.             ThrowIfGeneric();
  819.             ThrowIfShouldNotHaveBody();
  820.            
  821.             if (m_ilGenerator == null)
  822.                 m_ilGenerator = new ILGenerator(this);
  823.             return m_ilGenerator;
  824.         }
  825.        
  826.         public ILGenerator GetILGenerator(int size)
  827.         {
  828.             ThrowIfGeneric();
  829.             ThrowIfShouldNotHaveBody();
  830.            
  831.             if (m_ilGenerator == null)
  832.                 m_ilGenerator = new ILGenerator(this, size);
  833.             return m_ilGenerator;
  834.         }
  835.        
  836.         private void ThrowIfShouldNotHaveBody()
  837.         {
  838.             if ((m_dwMethodImplFlags & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL || (m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 || (m_iAttributes & MethodAttributes.PinvokeImpl) != 0 || m_isDllImport) {
  839.                 // cannot attach method body if methodimpl is marked not marked as managed IL
  840.                 //
  841.                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody"));
  842.             }
  843.         }
  844.        
  845.        
  846.         public bool InitLocals {
  847.             // Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false.
  848.             get {
  849.                 ThrowIfGeneric();
  850.                 return m_fInitLocals;
  851.             }
  852.             set {
  853.                 ThrowIfGeneric();
  854.                 m_fInitLocals = value;
  855.             }
  856.         }
  857.        
  858.         public Module GetModule()
  859.         {
  860.             return m_module;
  861.         }
  862.        
  863.         public string Signature {
  864.             get { return GetMethodSignature().ToString(); }
  865.         }
  866.        
  867.         [System.Runtime.InteropServices.ComVisible(true)]
  868.         public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
  869.         {
  870.             ThrowIfGeneric();
  871.            
  872.             if (con == null)
  873.                 throw new ArgumentNullException("con");
  874.             if (binaryAttribute == null)
  875.                 throw new ArgumentNullException("binaryAttribute");
  876.            
  877.             TypeBuilder.InternalCreateCustomAttribute(MetadataTokenInternal, ((ModuleBuilder)m_module).GetConstructorToken(con).Token, binaryAttribute, m_module, false);
  878.            
  879.             if (IsKnownCA(con))
  880.                 ParseCA(con, binaryAttribute);
  881.         }
  882.        
  883.         public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
  884.         {
  885.             ThrowIfGeneric();
  886.            
  887.             if (customBuilder == null)
  888.                 throw new ArgumentNullException("customBuilder");
  889.            
  890.             customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal);
  891.            
  892.             if (IsKnownCA(customBuilder.m_con))
  893.                 ParseCA(customBuilder.m_con, customBuilder.m_blob);
  894.         }
  895.        
  896.         // this method should return true for any and every ca that requires more work
  897.         // than just setting the ca
  898.         private bool IsKnownCA(ConstructorInfo con)
  899.         {
  900.             Type caType = con.DeclaringType;
  901.             if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
  902.                 return true;
  903.             else if (caType == typeof(DllImportAttribute))
  904.                 return true;
  905.             else
  906.                 return false;
  907.         }
  908.        
  909.         private void ParseCA(ConstructorInfo con, byte[] blob)
  910.         {
  911.             Type caType = con.DeclaringType;
  912.             if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) {
  913.                 // dig through the blob looking for the MethodImplAttributes flag
  914.                 // that must be in the MethodCodeType field
  915.                
  916.                 // for now we simply set a flag that relaxes the check when saving and
  917.                 // allows this method to have no body when any kind of MethodImplAttribute is present
  918.                 m_canBeRuntimeImpl = true;
  919.             }
  920.             else if (caType == typeof(DllImportAttribute)) {
  921.                 m_canBeRuntimeImpl = true;
  922.                 m_isDllImport = true;
  923.             }
  924.            
  925.         }
  926.        
  927.         internal bool m_canBeRuntimeImpl = false;
  928.         internal bool m_isDllImport = false;
  929.        
  930.         #endregion
  931.        
  932.         void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo)
  933.         {
  934.             throw new NotImplementedException();
  935.         }
  936.        
  937.         void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
  938.         {
  939.             throw new NotImplementedException();
  940.         }
  941.        
  942.         void _MethodBuilder.GetIDsOfNames(        [In()]
  943. ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
  944.         {
  945.             throw new NotImplementedException();
  946.         }
  947.        
  948.         void _MethodBuilder.Invoke(uint dispIdMember,         [In()]
  949. ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
  950.         {
  951.             throw new NotImplementedException();
  952.         }
  953.        
  954.     }
  955.    
  956.     internal class LocalSymInfo
  957.     {
  958.         // This class tracks the local variable's debugging information
  959.         // and namespace information with a given active lexical scope.
  960.        
  961.         #region Internal Data Members
  962.         internal string[] m_strName;
  963.         internal byte[][] m_ubSignature;
  964.         internal int[] m_iLocalSlot;
  965.         internal int[] m_iStartOffset;
  966.         internal int[] m_iEndOffset;
  967.         internal int m_iLocalSymCount;
  968.         // how many entries in the arrays are occupied
  969.         internal string[] m_namespace;
  970.         internal int m_iNameSpaceCount;
  971.         internal const int InitialSize = 16;
  972.         #endregion
  973.        
  974.         #region Constructor
  975.         internal LocalSymInfo()
  976.         {
  977.             // initialize data variables
  978.             m_iLocalSymCount = 0;
  979.             m_iNameSpaceCount = 0;
  980.         }
  981.         #endregion
  982.        
  983.         #region Private Members
  984.         private void EnsureCapacityNamespace()
  985.         {
  986.             if (m_iNameSpaceCount == 0) {
  987.                 m_namespace = new string[InitialSize];
  988.             }
  989.             else if (m_iNameSpaceCount == m_namespace.Length) {
  990.                 string[] strTemp = new string[m_iNameSpaceCount * 2];
  991.                 Array.Copy(m_namespace, strTemp, m_iNameSpaceCount);
  992.                 m_namespace = strTemp;
  993.                
  994.             }
  995.         }
  996.        
  997.         private void EnsureCapacity()
  998.         {
  999.             if (m_iLocalSymCount == 0) {
  1000.                 // First time. Allocate the arrays.
  1001.                 m_strName = new string[InitialSize];
  1002.                 m_ubSignature = new byte[InitialSize][];
  1003.                 m_iLocalSlot = new int[InitialSize];
  1004.                 m_iStartOffset = new int[InitialSize];
  1005.                 m_iEndOffset = new int[InitialSize];
  1006.             }
  1007.             else if (m_iLocalSymCount == m_strName.Length) {
  1008.                 // the arrays are full. Enlarge the arrays
  1009.                 int[] temp = new int[m_iLocalSymCount * 2];
  1010.                 Array.Copy(m_iLocalSlot, temp, m_iLocalSymCount);
  1011.                 m_iLocalSlot = temp;
  1012.                
  1013.                 temp = new int[m_iLocalSymCount * 2];
  1014.                 Array.Copy(m_iStartOffset, temp, m_iLocalSymCount);
  1015.                 m_iStartOffset = temp;
  1016.                
  1017.                 temp = new int[m_iLocalSymCount * 2];
  1018.                 Array.Copy(m_iEndOffset, temp, m_iLocalSymCount);
  1019.                 m_iEndOffset = temp;
  1020.                
  1021.                 string[] strTemp = new string[m_iLocalSymCount * 2];
  1022.                 Array.Copy(m_strName, strTemp, m_iLocalSymCount);
  1023.                 m_strName = strTemp;
  1024.                
  1025.                 byte[][] ubTemp = new byte[m_iLocalSymCount * 2][];
  1026.                 Array.Copy(m_ubSignature, ubTemp, m_iLocalSymCount);
  1027.                 m_ubSignature = ubTemp;
  1028.                
  1029.             }
  1030.         }
  1031.        
  1032.         #endregion
  1033.        
  1034.         #region Internal Members
  1035.         internal void AddLocalSymInfo(string strName, byte[] signature, int slot, int startOffset, int endOffset)
  1036.         {
  1037.             // make sure that arrays are large enough to hold addition info
  1038.             EnsureCapacity();
  1039.             m_iStartOffset[m_iLocalSymCount] = startOffset;
  1040.             m_iEndOffset[m_iLocalSymCount] = endOffset;
  1041.             m_iLocalSlot[m_iLocalSymCount] = slot;
  1042.             m_strName[m_iLocalSymCount] = strName;
  1043.             m_ubSignature[m_iLocalSymCount] = signature;
  1044.             m_iLocalSymCount++;
  1045.         }
  1046.        
  1047.         internal void AddUsingNamespace(string strNamespace)
  1048.         {
  1049.             EnsureCapacityNamespace();
  1050.             m_namespace[m_iNameSpaceCount++] = strNamespace;
  1051.            
  1052.         }
  1053.        
  1054.         internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
  1055.         {
  1056.             int i;
  1057.            
  1058.             for (i = 0; i < m_iLocalSymCount; i++) {
  1059.                     // addr2 is not used yet
  1060.                     // addr3 is not used
  1061.                 symWriter.DefineLocalVariable(m_strName[i], FieldAttributes.PrivateScope, m_ubSignature[i], SymAddressKind.ILOffset, m_iLocalSlot[i], 0, 0, m_iStartOffset[i], m_iEndOffset[i]);
  1062.             }
  1063.             for (i = 0; i < m_iNameSpaceCount; i++) {
  1064.                 symWriter.UsingNamespace(m_namespace[i]);
  1065.             }
  1066.         }
  1067.        
  1068.         #endregion
  1069.     }
  1070.    
  1071.     internal struct __ExceptionInstance
  1072.     {
  1073.         #region Internal Members
  1074.         // Keep in sync with unmanged structure.
  1075.         internal int m_exceptionClass;
  1076.         internal int m_startAddress;
  1077.         internal int m_endAddress;
  1078.         internal int m_filterAddress;
  1079.         internal int m_handleAddress;
  1080.         internal int m_handleEndAddress;
  1081.         internal int m_type;
  1082.         #endregion
  1083.        
  1084.         #region Constructor
  1085.         internal __ExceptionInstance(int start, int end, int filterAddr, int handle, int handleEnd, int type, int exceptionClass)
  1086.         {
  1087.             m_startAddress = start;
  1088.             m_endAddress = end;
  1089.             m_filterAddress = filterAddr;
  1090.             m_handleAddress = handle;
  1091.             m_handleEndAddress = handleEnd;
  1092.             m_type = type;
  1093.             m_exceptionClass = exceptionClass;
  1094.         }
  1095.         #endregion
  1096.        
  1097.         #region Object Overrides
  1098.         public override bool Equals(object obj)
  1099.         {
  1100.             if (obj != null && (obj is __ExceptionInstance)) {
  1101.                 __ExceptionInstance that = (__ExceptionInstance)obj;
  1102.                 return that.m_exceptionClass == m_exceptionClass && that.m_startAddress == m_startAddress && that.m_endAddress == m_endAddress && that.m_filterAddress == m_filterAddress && that.m_handleAddress == m_handleAddress && that.m_handleEndAddress == m_handleEndAddress;
  1103.             }
  1104.             else
  1105.                 return false;
  1106.         }
  1107.        
  1108.         public override int GetHashCode()
  1109.         {
  1110.             return m_exceptionClass ^ m_startAddress ^ m_endAddress ^ m_filterAddress ^ m_handleAddress ^ m_handleEndAddress ^ m_type;
  1111.         }
  1112.        
  1113.         #endregion
  1114.     }
  1115. }

Developer Fusion