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

  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 System.Reflection;
  20.     using System.Runtime.CompilerServices;
  21.     using System.Runtime.InteropServices;
  22.     using System.Security.Permissions;
  23.    
  24.     [ClassInterface(ClassInterfaceType.None)]
  25.     [ComDefaultInterface(typeof(_SignatureHelper))]
  26.     [System.Runtime.InteropServices.ComVisible(true)]
  27.     public sealed class SignatureHelper : _SignatureHelper
  28.     {
  29.         #region Consts Fields
  30.         internal const int mdtTypeRef = 16777216;
  31.         internal const int mdtTypeDef = 33554432;
  32.         internal const int mdtTypeSpec = 553648128;
  33.        
  34.         #region ElementType
  35.         //The following fields are duplicated from cor.h and must be kept in sync
  36.         internal const byte ELEMENT_TYPE_END = 0;
  37.         internal const byte ELEMENT_TYPE_VOID = 1;
  38.         internal const byte ELEMENT_TYPE_BOOLEAN = 2;
  39.         internal const byte ELEMENT_TYPE_CHAR = 3;
  40.         internal const byte ELEMENT_TYPE_I1 = 4;
  41.         internal const byte ELEMENT_TYPE_U1 = 5;
  42.         internal const byte ELEMENT_TYPE_I2 = 6;
  43.         internal const byte ELEMENT_TYPE_U2 = 7;
  44.         internal const byte ELEMENT_TYPE_I4 = 8;
  45.         internal const byte ELEMENT_TYPE_U4 = 9;
  46.         internal const byte ELEMENT_TYPE_I8 = 10;
  47.         internal const byte ELEMENT_TYPE_U8 = 11;
  48.         internal const byte ELEMENT_TYPE_R4 = 12;
  49.         internal const byte ELEMENT_TYPE_R8 = 13;
  50.         internal const byte ELEMENT_TYPE_STRING = 14;
  51.        
  52.         internal const byte ELEMENT_TYPE_PTR = 15;
  53.         // PTR <type>
  54.         internal const byte ELEMENT_TYPE_BYREF = 16;
  55.         // BYREF <type>
  56.         internal const byte ELEMENT_TYPE_VALUETYPE = 17;
  57.         // VALUETYPE <class Token>
  58.         internal const byte ELEMENT_TYPE_CLASS = 18;
  59.         // CLASS <class Token>
  60.         internal const byte ELEMENT_TYPE_VAR = 19;
  61.         // VAR <U1>
  62.         internal const byte ELEMENT_TYPE_ARRAY = 20;
  63.         // MDARRAY <type> <rank> <bcount> <bound1> ... <lbcount> <lb1> ...
  64.         internal const byte ELEMENT_TYPE_GENERICINST = 21;
  65.         // WITH <type> <ntypars> <type1> ... <typen>
  66.         internal const byte ELEMENT_TYPE_TYPEDBYREF = 22;
  67.         // This is a simple type.
  68.         internal const byte ELEMENT_TYPE_I = 24;
  69.         // native-pointer-sized integer.
  70.         internal const byte ELEMENT_TYPE_U = 25;
  71.         // native-pointer-sized unsigned integer.
  72.         internal const byte ELEMENT_TYPE_FNPTR = 27;
  73.         // FNPTR <complete sig for the function including calling convention>
  74.         internal const byte ELEMENT_TYPE_OBJECT = 28;
  75.         // Shortcut for System.Object
  76.         internal const byte ELEMENT_TYPE_SZARRAY = 29;
  77.         // SZARRAY <type> : Shortcut for single dimension zero lower bound array
  78.         internal const byte ELEMENT_TYPE_MVAR = 30;
  79.         // MVAR <U1>
  80.         internal const byte ELEMENT_TYPE_CMOD_REQD = 31;
  81.         // required C modifier : E_T_CMOD_REQD <mdTypeRef/mdTypeDef>
  82.         internal const byte ELEMENT_TYPE_CMOD_OPT = 32;
  83.         // optional C modifier : E_T_CMOD_OPT <mdTypeRef/mdTypeDef>
  84.         internal const byte ELEMENT_TYPE_INTERNAL = 33;
  85.        
  86.         internal const byte ELEMENT_TYPE_MAX = 34;
  87.         // first invalid element type
  88.         internal const byte ELEMENT_TYPE_SENTINEL = 65;
  89.         // SENTINEL for vararg
  90.         internal const byte ELEMENT_TYPE_PINNED = 69;
  91.         #endregion
  92.        
  93.         #region Unmanged Calling Convetions
  94.         internal const int IMAGE_CEE_UNMANAGED_CALLCONV_C = 1;
  95.         internal const int IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL = 2;
  96.         internal const int IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL = 3;
  97.         internal const int IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL = 4;
  98.         #endregion
  99.        
  100.         #region Managed Calling Conventions
  101.         internal const int IMAGE_CEE_CS_CALLCONV_DEFAULT = 0;
  102.         internal const int IMAGE_CEE_CS_CALLCONV_VARARG = 5;
  103.         internal const int IMAGE_CEE_CS_CALLCONV_FIELD = 6;
  104.         internal const int IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 7;
  105.         internal const int IMAGE_CEE_CS_CALLCONV_PROPERTY = 8;
  106.         internal const int IMAGE_CEE_CS_CALLCONV_UNMGD = 9;
  107.         internal const int IMAGE_CEE_CS_CALLCONV_GENERICINST = 10;
  108.         internal const int IMAGE_CEE_CS_CALLCONV_MAX = 11;
  109.         // first invalid calling convention
  110.         #endregion
  111.         #region Misc
  112.         // The high bits of the calling convention convey additional info
  113.         internal const int IMAGE_CEE_CS_CALLCONV_MASK = 15;
  114.         // Calling convention is bottom 4 bits
  115.         internal const int IMAGE_CEE_CS_CALLCONV_GENERIC = 16;
  116.         // Generic method sig with explicit number of type parameters
  117.         internal const int IMAGE_CEE_CS_CALLCONV_HASTHIS = 32;
  118.         // Top bit indicates a 'this' parameter
  119.         internal const int IMAGE_CEE_CS_CALLCONV_RETPARAM = 64;
  120.         // The first param in the sig is really the return value
  121.         internal const int NO_SIZE_IN_SIG = -1;
  122.         #endregion
  123.        
  124.         #endregion
  125.        
  126.         #region Static Members
  127.         public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
  128.         {
  129.             return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
  130.         }
  131.        
  132.         /// <include file='doc\SignatureHelper.uex' path='docs/doc[@for="SignatureHelper.GetMethodSigHelper"]/*' />
  133.         static internal SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam)
  134.         {
  135.             return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null);
  136.         }
  137.        
  138.         public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
  139.         {
  140.             return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null);
  141.         }
  142.        
  143.         static internal SignatureHelper GetMethodSpecSigHelper(Module scope, Type[] inst)
  144.         {
  145.             SignatureHelper sigHelp = new SignatureHelper(scope, IMAGE_CEE_CS_CALLCONV_GENERICINST);
  146.             sigHelp.AddData(inst.Length);
  147.             foreach (Type t in inst)
  148.                 sigHelp.AddArgument(t);
  149.             return sigHelp;
  150.         }
  151.        
  152.         static internal SignatureHelper GetMethodSigHelper(Module scope, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
  153.         {
  154.             return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
  155.         }
  156.        
  157.         static internal SignatureHelper GetMethodSigHelper(Module scope, CallingConventions callingConvention, int cGenericParam, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
  158.         {
  159.             SignatureHelper sigHelp;
  160.             int intCall;
  161.            
  162.             if (returnType == null) {
  163.                 returnType = typeof(void);
  164.             }
  165.            
  166.             intCall = IMAGE_CEE_CS_CALLCONV_DEFAULT;
  167.            
  168.             if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
  169.                 intCall = IMAGE_CEE_CS_CALLCONV_VARARG;
  170.            
  171.             if (cGenericParam > 0) {
  172.                 intCall |= IMAGE_CEE_CS_CALLCONV_GENERIC;
  173.             }
  174.            
  175.             if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
  176.                 intCall |= IMAGE_CEE_CS_CALLCONV_HASTHIS;
  177.            
  178.             sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
  179.             sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
  180.            
  181.             return sigHelp;
  182.         }
  183.        
  184.         public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
  185.         {
  186.             SignatureHelper sigHelp;
  187.             int intCall;
  188.            
  189.             if (returnType == null)
  190.                 returnType = typeof(void);
  191.            
  192.             if (unmanagedCallConv == CallingConvention.Cdecl) {
  193.                 intCall = IMAGE_CEE_UNMANAGED_CALLCONV_C;
  194.             }
  195.             else if (unmanagedCallConv == CallingConvention.StdCall || unmanagedCallConv == CallingConvention.Winapi) {
  196.                 intCall = IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL;
  197.             }
  198.             else if (unmanagedCallConv == CallingConvention.ThisCall) {
  199.                 intCall = IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL;
  200.             }
  201.             else if (unmanagedCallConv == CallingConvention.FastCall) {
  202.                 intCall = IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL;
  203.             }
  204.             else {
  205.                 throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv");
  206.             }
  207.            
  208.             sigHelp = new SignatureHelper(mod, intCall, returnType, null, null);
  209.            
  210.             return sigHelp;
  211.         }
  212.        
  213.         public static SignatureHelper GetLocalVarSigHelper()
  214.         {
  215.             return GetLocalVarSigHelper(null);
  216.         }
  217.        
  218.         public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
  219.         {
  220.             return GetMethodSigHelper(null, callingConvention, returnType);
  221.         }
  222.        
  223.         public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
  224.         {
  225.             return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
  226.         }
  227.        
  228.         public static SignatureHelper GetLocalVarSigHelper(Module mod)
  229.         {
  230.             return new SignatureHelper(mod, IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
  231.         }
  232.        
  233.         public static SignatureHelper GetFieldSigHelper(Module mod)
  234.         {
  235.             return new SignatureHelper(mod, IMAGE_CEE_CS_CALLCONV_FIELD);
  236.         }
  237.        
  238.         public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
  239.         {
  240.             return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null);
  241.         }
  242.        
  243.         public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
  244.         {
  245.             SignatureHelper sigHelp;
  246.            
  247.             if (returnType == null) {
  248.                 returnType = typeof(void);
  249.             }
  250.            
  251.             sigHelp = new SignatureHelper(mod, IMAGE_CEE_CS_CALLCONV_PROPERTY, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
  252.             sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
  253.            
  254.             return sigHelp;
  255.         }
  256.        
  257.         static internal SignatureHelper GetTypeSigToken(Module mod, Type type)
  258.         {
  259.             if (mod == null)
  260.                 throw new ArgumentNullException("module");
  261.            
  262.             if (type == null)
  263.                 throw new ArgumentNullException("type");
  264.            
  265.             return new SignatureHelper(mod, type);
  266.         }
  267.         #endregion
  268.        
  269.         #region Private Data Members
  270.         private byte[] m_signature;
  271.         private int m_currSig;
  272.         // index into m_signature buffer for next available byte
  273.         private int m_sizeLoc;
  274.         // size of the m_signature buffer
  275.         private ModuleBuilder m_module;
  276.         private bool m_sigDone;
  277.         private int m_argCount;
  278.         // tracking number of arguments in the signature
  279.         #endregion
  280.         #region Constructor
  281.         private SignatureHelper(Module mod, int callingConvention)
  282.         {
  283.             // Use this constructor to instantiate a local var sig or Field where return type is not applied.
  284.             Init(mod, callingConvention);
  285.         }
  286.        
  287.         private SignatureHelper(Module mod, int callingConvention, int cGenericParameters, Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
  288.         {
  289.             // Use this constructor to instantiate a any signatures that will require a return type.
  290.             Init(mod, callingConvention, cGenericParameters);
  291.            
  292.             if (callingConvention == IMAGE_CEE_CS_CALLCONV_FIELD)
  293.                 throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig"));
  294.            
  295.             AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
  296.         }
  297.        
  298.         private SignatureHelper(Module mod, int callingConvention, Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) : this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers)
  299.         {
  300.         }
  301.        
  302.         private SignatureHelper(Module mod, Type type)
  303.         {
  304.             Init(mod);
  305.            
  306.             AddOneArgTypeHelper(type);
  307.         }
  308.        
  309.         private void Init(Module mod)
  310.         {
  311.             m_signature = new byte[32];
  312.             m_currSig = 0;
  313.             m_module = mod as ModuleBuilder;
  314.             m_argCount = 0;
  315.             m_sigDone = false;
  316.             m_sizeLoc = NO_SIZE_IN_SIG;
  317.            
  318.             if (m_module == null && mod != null)
  319.                 throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder"));
  320.         }
  321.        
  322.         private void Init(Module mod, int callingConvention)
  323.         {
  324.             Init(mod, callingConvention, 0);
  325.         }
  326.        
  327.         private void Init(Module mod, int callingConvention, int cGenericParam)
  328.         {
  329.             Init(mod);
  330.            
  331.             AddData(callingConvention);
  332.            
  333.             if (callingConvention == IMAGE_CEE_CS_CALLCONV_FIELD || callingConvention == IMAGE_CEE_CS_CALLCONV_GENERICINST) {
  334.                 m_sizeLoc = NO_SIZE_IN_SIG;
  335.             }
  336.             else {
  337.                 if (cGenericParam > 0)
  338.                     AddData(cGenericParam);
  339.                
  340.                 m_sizeLoc = m_currSig++;
  341.             }
  342.         }
  343.        
  344.         #endregion
  345.        
  346.         #region Private Members
  347.         private void AddOneArgTypeHelper(Type argument, bool pinned)
  348.         {
  349.             if (pinned)
  350.                 AddElementType(ELEMENT_TYPE_PINNED);
  351.            
  352.             AddOneArgTypeHelper(argument);
  353.         }
  354.        
  355.         private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
  356.         {
  357.             // This function will not increase the argument count. It only fills in bytes
  358.             // in the signature based on clsArgument. This helper is called for return type.
  359.            
  360.             ASSERT.PRECONDITION(clsArgument != null);
  361.             ASSERT.PRECONDITION((optionalCustomModifiers == null && requiredCustomModifiers == null) || !clsArgument.ContainsGenericParameters);
  362.             ASSERT.PRECONDITION(requiredCustomModifiers == null || Array.IndexOf(requiredCustomModifiers, null) == -1);
  363.             ASSERT.PRECONDITION(optionalCustomModifiers == null || Array.IndexOf(optionalCustomModifiers, null) == -1);
  364.            
  365.             if (optionalCustomModifiers != null) {
  366.                 for (int i = 0; i < optionalCustomModifiers.Length; i++) {
  367.                     AddElementType(ELEMENT_TYPE_CMOD_OPT);
  368.                     ASSERT.CONSISTENCY_CHECK(!MetadataToken.IsNullToken(optionalCustomModifiers[i].MetadataTokenInternal));
  369.                     AddToken(m_module.GetTypeToken(optionalCustomModifiers[i]).Token);
  370.                 }
  371.             }
  372.            
  373.             if (requiredCustomModifiers != null) {
  374.                 for (int i = 0; i < requiredCustomModifiers.Length; i++) {
  375.                     AddElementType(ELEMENT_TYPE_CMOD_REQD);
  376.                     ASSERT.CONSISTENCY_CHECK(!MetadataToken.IsNullToken(requiredCustomModifiers[i].MetadataTokenInternal));
  377.                     AddToken(m_module.GetTypeToken(requiredCustomModifiers[i]).Token);
  378.                 }
  379.             }
  380.            
  381.             AddOneArgTypeHelper(clsArgument);
  382.         }
  383.        
  384.         private void AddOneArgTypeHelper(Type clsArgument)
  385.         {
  386.             AddOneArgTypeHelperWorker(clsArgument, false);
  387.         }
  388.         private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst)
  389.         {
  390.             if (clsArgument.IsGenericParameter) {
  391.                 if (clsArgument.DeclaringMethod != null)
  392.                     AddData(ELEMENT_TYPE_MVAR);
  393.                 else
  394.                     AddData(ELEMENT_TYPE_VAR);
  395.                
  396.                 AddData(clsArgument.GenericParameterPosition);
  397.             }
  398.             else if (clsArgument.IsGenericType && (!clsArgument.IsGenericTypeDefinition || !lastWasGenericInst)) {
  399.                 AddElementType(ELEMENT_TYPE_GENERICINST);
  400.                
  401.                 AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true);
  402.                
  403.                 Type[] args = clsArgument.GetGenericArguments();
  404.                
  405.                 AddData(args.Length);
  406.                
  407.                 foreach (Type t in args)
  408.                     AddOneArgTypeHelper(t);
  409.             }
  410.             else if (clsArgument is TypeBuilder) {
  411.                 TypeBuilder clsBuilder = (TypeBuilder)clsArgument;
  412.                 TypeToken tkType;
  413.                
  414.                 if (clsBuilder.Module == m_module) {
  415.                     tkType = clsBuilder.TypeToken;
  416.                 }
  417.                 else {
  418.                     tkType = m_module.GetTypeToken(clsArgument);
  419.                 }
  420.                
  421.                 if (clsArgument.IsValueType) {
  422.                     InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE);
  423.                 }
  424.                 else {
  425.                     InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS);
  426.                 }
  427.             }
  428.             else if (clsArgument is EnumBuilder) {
  429.                 TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder;
  430.                 TypeToken tkType;
  431.                
  432.                 if (clsBuilder.Module == m_module) {
  433.                     tkType = clsBuilder.TypeToken;
  434.                 }
  435.                 else {
  436.                     tkType = m_module.GetTypeToken(clsArgument);
  437.                 }
  438.                
  439.                 if (clsArgument.IsValueType) {
  440.                     InternalAddTypeToken(tkType, ELEMENT_TYPE_VALUETYPE);
  441.                 }
  442.                 else {
  443.                     InternalAddTypeToken(tkType, ELEMENT_TYPE_CLASS);
  444.                 }
  445.             }
  446.             else if (clsArgument.IsByRef) {
  447.                 AddElementType(ELEMENT_TYPE_BYREF);
  448.                 clsArgument = clsArgument.GetElementType();
  449.                 AddOneArgTypeHelper(clsArgument);
  450.             }
  451.             else if (clsArgument.IsPointer) {
  452.                 AddElementType(ELEMENT_TYPE_PTR);
  453.                 AddOneArgTypeHelper(clsArgument.GetElementType());
  454.             }
  455.             else if (clsArgument.IsArray) {
  456.                 if (clsArgument.IsSzArray) {
  457.                     AddElementType(ELEMENT_TYPE_SZARRAY);
  458.                    
  459.                     AddOneArgTypeHelper(clsArgument.GetElementType());
  460.                 }
  461.                 else {
  462.                     AddElementType(ELEMENT_TYPE_ARRAY);
  463.                    
  464.                     AddOneArgTypeHelper(clsArgument.GetElementType());
  465.                    
  466.                     // put the rank information
  467.                     AddData(clsArgument.GetArrayRank());
  468.                    
  469.                     AddData(0);
  470.                     AddData(0);
  471.                 }
  472.             }
  473.             else {
  474.                 RuntimeType rType = clsArgument as RuntimeType;
  475.                 int type = rType != null ? GetCorElementTypeFromClass(rType) : ELEMENT_TYPE_MAX;
  476.                
  477.                 if (IsSimpleType(type)) {
  478.                     AddElementType(type);
  479.                 }
  480.                 else {
  481.                     if (clsArgument == typeof(object)) {
  482.                         AddElementType(ELEMENT_TYPE_OBJECT);
  483.                     }
  484.                     else if (clsArgument == typeof(string)) {
  485.                         AddElementType(ELEMENT_TYPE_STRING);
  486.                     }
  487.                     else {
  488.                         if (m_module == null) {
  489.                             InternalAddRuntimeType(rType);
  490.                         }
  491.                         else {
  492.                             if (clsArgument.IsValueType) {
  493.                                 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_VALUETYPE);
  494.                             }
  495.                             else {
  496.                                 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), ELEMENT_TYPE_CLASS);
  497.                             }
  498.                         }
  499.                     }
  500.                 }
  501.             }
  502.         }
  503.        
  504.         private void AddData(int data)
  505.         {
  506.             // A managed representation of CorSigCompressData;
  507.            
  508.             if (m_currSig + 4 >= m_signature.Length) {
  509.                 m_signature = ExpandArray(m_signature);
  510.             }
  511.            
  512.             if (data <= 127) {
  513.                 m_signature[m_currSig++] = (byte)(data & 255);
  514.             }
  515.             else if (data <= 16383) {
  516.                 m_signature[m_currSig++] = (byte)((data >> 8) | 128);
  517.                 m_signature[m_currSig++] = (byte)(data & 255);
  518.             }
  519.             else if (data <= 536870911) {
  520.                 m_signature[m_currSig++] = (byte)((data >> 24) | 192);
  521.                 m_signature[m_currSig++] = (byte)((data >> 16) & 255);
  522.                 m_signature[m_currSig++] = (byte)((data >> 8) & 255);
  523.                 m_signature[m_currSig++] = (byte)((data)&255);
  524.             }
  525.             else {
  526.                 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
  527.             }
  528.            
  529.         }
  530.        
  531.         private void AddData(uint data)
  532.         {
  533.             if (m_currSig + 4 >= m_signature.Length) {
  534.                 m_signature = ExpandArray(m_signature);
  535.             }
  536.            
  537.             m_signature[m_currSig++] = (byte)((data)&255);
  538.             m_signature[m_currSig++] = (byte)((data >> 8) & 255);
  539.             m_signature[m_currSig++] = (byte)((data >> 16) & 255);
  540.             m_signature[m_currSig++] = (byte)((data >> 24) & 255);
  541.         }
  542.        
  543.         private void AddData(ulong data)
  544.         {
  545.             if (m_currSig + 8 >= m_signature.Length) {
  546.                 m_signature = ExpandArray(m_signature);
  547.             }
  548.            
  549.             m_signature[m_currSig++] = (byte)((data)&255);
  550.             m_signature[m_currSig++] = (byte)((data >> 8) & 255);
  551.             m_signature[m_currSig++] = (byte)((data >> 16) & 255);
  552.             m_signature[m_currSig++] = (byte)((data >> 24) & 255);
  553.             m_signature[m_currSig++] = (byte)((data >> 32) & 255);
  554.             m_signature[m_currSig++] = (byte)((data >> 40) & 255);
  555.             m_signature[m_currSig++] = (byte)((data >> 48) & 255);
  556.             m_signature[m_currSig++] = (byte)((data >> 56) & 255);
  557.         }
  558.        
  559.         private void AddElementType(int cvt)
  560.         {
  561.             // Adds an element to the signature. A managed represenation of CorSigCompressElement
  562.             if (m_currSig + 1 >= m_signature.Length)
  563.                 m_signature = ExpandArray(m_signature);
  564.            
  565.             m_signature[m_currSig++] = (byte)cvt;
  566.         }
  567.        
  568.         private void AddToken(int token)
  569.         {
  570.             // A managed represenation of CompressToken
  571.             // Pulls the token appart to get a rid, adds some appropriate bits
  572.             // to the token and then adds this to the signature.
  573.            
  574.             int rid = (token & 16777215);
  575.             //This is RidFromToken;
  576.             int type = (token & unchecked((int)4278190080u));
  577.             //This is TypeFromToken;
  578.             if (rid > 67108863) {
  579.                 // token is too big to be compressed
  580.                 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
  581.             }
  582.            
  583.             rid = (rid << 2);
  584.            
  585.             // TypeDef is encoded with low bits 00
  586.             // TypeRef is encoded with low bits 01
  587.             // TypeSpec is encoded with low bits 10
  588.             if (type == mdtTypeRef) {
  589.                 //if type is mdtTypeRef
  590.                 rid |= 1;
  591.             }
  592.             else if (type == mdtTypeSpec) {
  593.                 //if type is mdtTypeSpec
  594.                 rid |= 2;
  595.             }
  596.            
  597.             AddData(rid);
  598.         }
  599.        
  600.         private void InternalAddTypeToken(TypeToken clsToken, int CorType)
  601.         {
  602.             // Add a type token into signature. CorType will be either ELEMENT_TYPE_CLASS or ELEMENT_TYPE_VALUECLASS
  603.             AddElementType(CorType);
  604.             AddToken(clsToken.Token);
  605.         }
  606.        
  607.         unsafe private void InternalAddRuntimeType(Type type)
  608.         {
  609.             // Add a runtime type into the signature.
  610.            
  611.             AddElementType(ELEMENT_TYPE_INTERNAL);
  612.         }
  613.        
  614.         void* handle = (void*)type.GetTypeHandleInternal().Value;
  615.     }
  616. }

Developer Fusion