3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>Microsoft</OWNER>
9 namespace System.Reflection.Emit
13 using System.Diagnostics.Contracts;
14 using System.Reflection;
15 using System.Runtime.CompilerServices;
16 using System.Runtime.InteropServices;
17 using System.Runtime.Versioning;
18 using System.Security.Permissions;
20 [ClassInterface(ClassInterfaceType.None)]
21 [ComDefaultInterface(typeof(_SignatureHelper))]
22 [System.Runtime.InteropServices.ComVisible(true)]
23 public sealed class SignatureHelper : _SignatureHelper
26 private const int NO_SIZE_IN_SIG = -1;
29 #region Static Members
30 [System.Security.SecuritySafeCritical] // auto-generated
31 public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
33 return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
36 [System.Security.SecurityCritical] // auto-generated
37 internal static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam)
39 return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null);
42 [System.Security.SecuritySafeCritical] // auto-generated
43 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
45 return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null);
48 internal static SignatureHelper GetMethodSpecSigHelper(Module scope, Type[] inst)
50 SignatureHelper sigHelp = new SignatureHelper(scope, MdSigCallingConvention.GenericInst);
51 sigHelp.AddData(inst.Length);
52 foreach(Type t in inst)
53 sigHelp.AddArgument(t);
57 [System.Security.SecurityCritical] // auto-generated
58 internal static SignatureHelper GetMethodSigHelper(
59 Module scope, CallingConventions callingConvention,
60 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
61 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
63 return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers,
64 optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
67 [System.Security.SecurityCritical] // auto-generated
68 internal static SignatureHelper GetMethodSigHelper(
69 Module scope, CallingConventions callingConvention, int cGenericParam,
70 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
71 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
73 SignatureHelper sigHelp;
74 MdSigCallingConvention intCall;
76 if (returnType == null)
78 returnType = typeof(void);
81 intCall = MdSigCallingConvention.Default;
83 if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
84 intCall = MdSigCallingConvention.Vararg;
86 if (cGenericParam > 0)
88 intCall |= MdSigCallingConvention.Generic;
91 if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
92 intCall |= MdSigCallingConvention.HasThis;
94 sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType,
95 requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
96 sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
101 [System.Security.SecuritySafeCritical] // auto-generated
102 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
104 SignatureHelper sigHelp;
105 MdSigCallingConvention intCall;
107 if (returnType == null)
108 returnType = typeof(void);
110 if (unmanagedCallConv == CallingConvention.Cdecl)
112 intCall = MdSigCallingConvention.C;
114 else if (unmanagedCallConv == CallingConvention.StdCall || unmanagedCallConv == CallingConvention.Winapi)
116 intCall = MdSigCallingConvention.StdCall;
118 else if (unmanagedCallConv == CallingConvention.ThisCall)
120 intCall = MdSigCallingConvention.ThisCall;
122 else if (unmanagedCallConv == CallingConvention.FastCall)
124 intCall = MdSigCallingConvention.FastCall;
128 throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv");
131 sigHelp = new SignatureHelper(mod, intCall, returnType, null, null);
136 public static SignatureHelper GetLocalVarSigHelper()
138 return GetLocalVarSigHelper(null);
141 public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
143 return GetMethodSigHelper(null, callingConvention, returnType);
146 public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
148 return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
151 public static SignatureHelper GetLocalVarSigHelper(Module mod)
153 return new SignatureHelper(mod, MdSigCallingConvention.LocalSig);
156 public static SignatureHelper GetFieldSigHelper(Module mod)
158 return new SignatureHelper(mod, MdSigCallingConvention.Field);
161 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
163 return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null);
166 public static SignatureHelper GetPropertySigHelper(Module mod,
167 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
168 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
170 return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
171 parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
173 [System.Security.SecuritySafeCritical] // auto-generated
174 public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention,
175 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
176 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
178 SignatureHelper sigHelp;
180 if (returnType == null)
182 returnType = typeof(void);
185 MdSigCallingConvention intCall = MdSigCallingConvention.Property;
187 if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
188 intCall |= MdSigCallingConvention.HasThis;
190 sigHelp = new SignatureHelper(mod, intCall,
191 returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
192 sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
197 [System.Security.SecurityCritical] // auto-generated
198 internal static SignatureHelper GetTypeSigToken(Module mod, Type type)
201 throw new ArgumentNullException("module");
204 throw new ArgumentNullException("type");
206 return new SignatureHelper(mod, type);
210 #region Private Data Members
211 private byte[] m_signature;
212 private int m_currSig; // index into m_signature buffer for next available byte
213 private int m_sizeLoc; // index into m_signature buffer to put m_argCount (will be NO_SIZE_IN_SIG if no arg count is needed)
214 private ModuleBuilder m_module;
215 private bool m_sigDone;
216 private int m_argCount; // tracking number of arguments in the signature
220 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention)
222 // Use this constructor to instantiate a local var sig or Field where return type is not applied.
223 Init(mod, callingConvention);
226 [System.Security.SecurityCritical] // auto-generated
227 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters,
228 Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
230 // Use this constructor to instantiate a any signatures that will require a return type.
231 Init(mod, callingConvention, cGenericParameters);
233 if (callingConvention == MdSigCallingConvention.Field)
234 throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig"));
236 AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
239 [System.Security.SecurityCritical] // auto-generated
240 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention,
241 Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
242 : this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers)
246 [System.Security.SecurityCritical] // auto-generated
247 private SignatureHelper(Module mod, Type type)
251 AddOneArgTypeHelper(type);
254 private void Init(Module mod)
256 m_signature = new byte[32];
258 m_module = mod as ModuleBuilder;
261 m_sizeLoc = NO_SIZE_IN_SIG;
263 if (m_module == null && mod != null)
264 throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder"));
267 private void Init(Module mod, MdSigCallingConvention callingConvention)
269 Init(mod, callingConvention, 0);
272 private void Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam)
276 AddData((byte)callingConvention);
278 if (callingConvention == MdSigCallingConvention.Field ||
279 callingConvention == MdSigCallingConvention.GenericInst)
281 m_sizeLoc = NO_SIZE_IN_SIG;
285 if (cGenericParam > 0)
286 AddData(cGenericParam);
288 m_sizeLoc = m_currSig++;
294 #region Private Members
295 [System.Security.SecurityCritical] // auto-generated
296 private void AddOneArgTypeHelper(Type argument, bool pinned)
299 AddElementType(CorElementType.Pinned);
301 AddOneArgTypeHelper(argument);
304 [System.Security.SecurityCritical] // auto-generated
305 private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
307 // This function will not increase the argument count. It only fills in bytes
308 // in the signature based on clsArgument. This helper is called for return type.
310 Contract.Requires(clsArgument != null);
311 Contract.Requires((optionalCustomModifiers == null && requiredCustomModifiers == null) || !clsArgument.ContainsGenericParameters);
313 if (optionalCustomModifiers != null)
315 for (int i = 0; i < optionalCustomModifiers.Length; i++)
317 Type t = optionalCustomModifiers[i];
320 throw new ArgumentNullException("optionalCustomModifiers");
322 if (t.HasElementType)
323 throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "optionalCustomModifiers");
325 if (t.ContainsGenericParameters)
326 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "optionalCustomModifiers");
328 AddElementType(CorElementType.CModOpt);
330 int token = m_module.GetTypeToken(t).Token;
331 Contract.Assert(!MetadataToken.IsNullToken(token));
336 if (requiredCustomModifiers != null)
338 for (int i = 0; i < requiredCustomModifiers.Length; i++)
340 Type t = requiredCustomModifiers[i];
343 throw new ArgumentNullException("requiredCustomModifiers");
345 if (t.HasElementType)
346 throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "requiredCustomModifiers");
348 if (t.ContainsGenericParameters)
349 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "requiredCustomModifiers");
351 AddElementType(CorElementType.CModReqd);
353 int token = m_module.GetTypeToken(t).Token;
354 Contract.Assert(!MetadataToken.IsNullToken(token));
359 AddOneArgTypeHelper(clsArgument);
362 [System.Security.SecurityCritical] // auto-generated
363 private void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); }
364 [System.Security.SecurityCritical] // auto-generated
365 private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst)
367 if (clsArgument.IsGenericParameter)
369 if (clsArgument.DeclaringMethod != null)
370 AddElementType(CorElementType.MVar);
372 AddElementType(CorElementType.Var);
374 AddData(clsArgument.GenericParameterPosition);
376 else if (clsArgument.IsGenericType && (!clsArgument.IsGenericTypeDefinition || !lastWasGenericInst))
378 AddElementType(CorElementType.GenericInst);
380 AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true);
382 Type[] args = clsArgument.GetGenericArguments();
384 AddData(args.Length);
386 foreach (Type t in args)
387 AddOneArgTypeHelper(t);
389 else if (clsArgument is TypeBuilder)
391 TypeBuilder clsBuilder = (TypeBuilder)clsArgument;
394 if (clsBuilder.Module.Equals(m_module))
396 tkType = clsBuilder.TypeToken;
400 tkType = m_module.GetTypeToken(clsArgument);
403 if (clsArgument.IsValueType)
405 InternalAddTypeToken(tkType, CorElementType.ValueType);
409 InternalAddTypeToken(tkType, CorElementType.Class);
412 else if (clsArgument is EnumBuilder)
414 TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder;
417 if (clsBuilder.Module.Equals(m_module))
419 tkType = clsBuilder.TypeToken;
423 tkType = m_module.GetTypeToken(clsArgument);
426 if (clsArgument.IsValueType)
428 InternalAddTypeToken(tkType, CorElementType.ValueType);
432 InternalAddTypeToken(tkType, CorElementType.Class);
435 else if (clsArgument.IsByRef)
437 AddElementType(CorElementType.ByRef);
438 clsArgument = clsArgument.GetElementType();
439 AddOneArgTypeHelper(clsArgument);
441 else if (clsArgument.IsPointer)
443 AddElementType(CorElementType.Ptr);
444 AddOneArgTypeHelper(clsArgument.GetElementType());
446 else if (clsArgument.IsArray)
448 if (clsArgument.IsSzArray)
450 AddElementType(CorElementType.SzArray);
452 AddOneArgTypeHelper(clsArgument.GetElementType());
456 AddElementType(CorElementType.Array);
458 AddOneArgTypeHelper(clsArgument.GetElementType());
460 // put the rank information
461 int rank = clsArgument.GetArrayRank();
462 AddData(rank); // rank
463 AddData(0); // upper bounds
464 AddData(rank); // lower bound
465 for (int i = 0; i < rank; i++)
471 CorElementType type = CorElementType.Max;
473 if (clsArgument is RuntimeType)
475 type = RuntimeTypeHandle.GetCorElementType((RuntimeType)clsArgument);
477 //GetCorElementType returns CorElementType.Class for both object and string
478 if (type == CorElementType.Class)
480 if (clsArgument == typeof(object))
481 type = CorElementType.Object;
482 else if (clsArgument == typeof(string))
483 type = CorElementType.String;
487 if (IsSimpleType(type))
489 AddElementType(type);
491 else if (m_module == null)
493 InternalAddRuntimeType(clsArgument);
495 else if (clsArgument.IsValueType)
497 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.ValueType);
501 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.Class);
506 private void AddData(int data)
508 // A managed representation of CorSigCompressData;
510 if (m_currSig + 4 > m_signature.Length)
512 m_signature = ExpandArray(m_signature);
517 m_signature[m_currSig++] = (byte)(data & 0xFF);
519 else if (data <= 0x3FFF)
521 m_signature[m_currSig++] = (byte)((data >>8) | 0x80);
522 m_signature[m_currSig++] = (byte)(data & 0xFF);
524 else if (data <= 0x1FFFFFFF)
526 m_signature[m_currSig++] = (byte)((data >>24) | 0xC0);
527 m_signature[m_currSig++] = (byte)((data >>16) & 0xFF);
528 m_signature[m_currSig++] = (byte)((data >>8) & 0xFF);
529 m_signature[m_currSig++] = (byte)((data) & 0xFF);
533 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
538 private void AddData(uint data)
540 if (m_currSig + 4 > m_signature.Length)
542 m_signature = ExpandArray(m_signature);
545 m_signature[m_currSig++] = (byte)((data) & 0xFF);
546 m_signature[m_currSig++] = (byte)((data>>8) & 0xFF);
547 m_signature[m_currSig++] = (byte)((data>>16) & 0xFF);
548 m_signature[m_currSig++] = (byte)((data>>24) & 0xFF);
551 private void AddData(ulong data)
553 if (m_currSig + 8 > m_signature.Length)
555 m_signature = ExpandArray(m_signature);
558 m_signature[m_currSig++] = (byte)((data) & 0xFF);
559 m_signature[m_currSig++] = (byte)((data>>8) & 0xFF);
560 m_signature[m_currSig++] = (byte)((data>>16) & 0xFF);
561 m_signature[m_currSig++] = (byte)((data>>24) & 0xFF);
562 m_signature[m_currSig++] = (byte)((data>>32) & 0xFF);
563 m_signature[m_currSig++] = (byte)((data>>40) & 0xFF);
564 m_signature[m_currSig++] = (byte)((data>>48) & 0xFF);
565 m_signature[m_currSig++] = (byte)((data>>56) & 0xFF);
568 private void AddElementType(CorElementType cvt)
570 // Adds an element to the signature. A managed represenation of CorSigCompressElement
571 if (m_currSig + 1 > m_signature.Length)
572 m_signature = ExpandArray(m_signature);
574 m_signature[m_currSig++] = (byte)cvt;
577 private void AddToken(int token)
579 // A managed represenation of CompressToken
580 // Pulls the token appart to get a rid, adds some appropriate bits
581 // to the token and then adds this to the signature.
583 int rid = (token & 0x00FFFFFF); //This is RidFromToken;
584 MetadataTokenType type = (MetadataTokenType)(token & unchecked((int)0xFF000000)); //This is TypeFromToken;
588 // token is too big to be compressed
589 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
594 // TypeDef is encoded with low bits 00
595 // TypeRef is encoded with low bits 01
596 // TypeSpec is encoded with low bits 10
597 if (type == MetadataTokenType.TypeRef)
599 //if type is mdtTypeRef
602 else if (type == MetadataTokenType.TypeSpec)
604 //if type is mdtTypeSpec
611 private void InternalAddTypeToken(TypeToken clsToken, CorElementType CorType)
613 // Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType
614 AddElementType(CorType);
615 AddToken(clsToken.Token);
618 [System.Security.SecurityCritical] // auto-generated
619 private unsafe void InternalAddRuntimeType(Type type)
621 // Add a runtime type into the signature.
623 AddElementType(CorElementType.Internal);
625 IntPtr handle = type.GetTypeHandleInternal().Value;
627 // Internal types must have their pointer written into the signature directly (we don't
628 // want to convert to little-endian format on big-endian machines because the value is
629 // going to be extracted and used directly as a pointer (and only within this process)).
631 if (m_currSig + sizeof(void*) > m_signature.Length)
632 m_signature = ExpandArray(m_signature);
634 byte *phandle = (byte*)&handle;
635 for (int i = 0; i < sizeof(void*); i++)
636 m_signature[m_currSig++] = phandle[i];
639 private byte[] ExpandArray(byte[] inArray)
641 // Expand the signature buffer size
642 return ExpandArray(inArray, inArray.Length * 2);
645 private byte[] ExpandArray(byte[] inArray, int requiredLength)
647 // Expand the signature buffer size
649 if (requiredLength < inArray.Length)
650 requiredLength = inArray.Length*2;
652 byte[] outArray = new byte[requiredLength];
653 Array.Copy(inArray, outArray, inArray.Length);
657 private void IncrementArgCounts()
659 if (m_sizeLoc == NO_SIZE_IN_SIG)
661 //We don't have a size if this is a field.
668 private void SetNumberOfSignatureElements(bool forceCopy)
670 // For most signatures, this will set the number of elements in a byte which we have reserved for it.
671 // However, if we have a field signature, we don't set the length and return.
672 // If we have a signature with more than 128 arguments, we can't just set the number of elements,
673 // we actually have to allocate more space (e.g. shift everything in the array one or more spaces to the
674 // right. We do this by making a copy of the array and leaving the correct number of blanks. This new
675 // array is now set to be m_signature and we use the AddData method to set the number of elements properly.
676 // The forceCopy argument can be used to force SetNumberOfSignatureElements to make a copy of
677 // the array. This is useful for GetSignature which promises to trim the array to be the correct size anyway.
681 int currSigHolder = m_currSig;
683 if (m_sizeLoc == NO_SIZE_IN_SIG)
686 //If we have fewer than 128 arguments and we haven't been told to copy the
687 //array, we can just set the appropriate bit and return.
688 if (m_argCount < 0x80 && !forceCopy)
690 m_signature[m_sizeLoc] = (byte)m_argCount;
694 //We need to have more bytes for the size. Figure out how many bytes here.
695 //Since we need to copy anyway, we're just going to take the cost of doing a
697 if (m_argCount < 0x80)
701 else if (m_argCount < 0x4000)
710 //Allocate the new array.
711 temp = new byte[m_currSig + newSigSize - 1];
713 //Copy the calling convention. The calling convention is always just one byte
714 //so we just copy that byte. Then copy the rest of the array, shifting everything
715 //to make room for the new number of elements.
716 temp[0] = m_signature[0];
717 Array.Copy(m_signature, m_sizeLoc + 1, temp, m_sizeLoc + newSigSize, currSigHolder - (m_sizeLoc + 1));
720 //Use the AddData method to add the number of elements appropriately compressed.
721 m_currSig = m_sizeLoc;
723 m_currSig = currSigHolder + (newSigSize - 1);
728 #region Internal Members
729 internal int ArgumentCount
737 internal static bool IsSimpleType(CorElementType type)
739 if (type <= CorElementType.String)
742 if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object)
748 internal byte[] InternalGetSignature(out int length)
750 // An internal method to return the signature. Does not trim the
751 // array, but passes out the length of the array in an out parameter.
752 // This is the actual array -- not a copy -- so the callee must agree
755 // param length : an out param indicating the length of the array.
756 // return : A reference to the internal ubyte array.
762 // If we have more than 128 variables, we can't just set the length, we need
763 // to compress it. Unfortunately, this means that we need to copy the entire
764 // array. Bummer, eh?
765 SetNumberOfSignatureElements(false);
775 internal byte[] InternalGetSignatureArray()
777 int argCount = m_argCount;
778 int currSigLength = m_currSig;
779 int newSigSize = currSigLength;
781 //Allocate the new array.
784 else if (argCount < 0x3FFF)
788 byte[] temp = new byte[newSigSize];
791 int sigCopyIndex = 0;
792 // calling convention
793 temp[sigCopyIndex++] = m_signature[0];
795 if (argCount <= 0x7F)
796 temp[sigCopyIndex++] = (byte)(argCount & 0xFF);
797 else if (argCount <= 0x3FFF)
799 temp[sigCopyIndex++] = (byte)((argCount >>8) | 0x80);
800 temp[sigCopyIndex++] = (byte)(argCount & 0xFF);
802 else if (argCount <= 0x1FFFFFFF)
804 temp[sigCopyIndex++] = (byte)((argCount >>24) | 0xC0);
805 temp[sigCopyIndex++] = (byte)((argCount >>16) & 0xFF);
806 temp[sigCopyIndex++] = (byte)((argCount >>8) & 0xFF);
807 temp[sigCopyIndex++] = (byte)((argCount) & 0xFF);
810 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
811 // copy the sig part of the sig
812 Array.Copy(m_signature, 2, temp, sigCopyIndex, currSigLength - 2);
813 // mark the end of sig
814 temp[newSigSize - 1] = (byte)CorElementType.End;
821 #region Public Methods
822 public void AddArgument(Type clsArgument)
824 AddArgument(clsArgument, null, null);
827 [System.Security.SecuritySafeCritical] // auto-generated
828 public void AddArgument(Type argument, bool pinned)
830 if (argument == null)
831 throw new ArgumentNullException("argument");
833 IncrementArgCounts();
834 AddOneArgTypeHelper(argument, pinned);
837 public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
839 if (requiredCustomModifiers != null && (arguments == null || requiredCustomModifiers.Length != arguments.Length))
840 throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "requiredCustomModifiers", "arguments"));
842 if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length))
843 throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "optionalCustomModifiers", "arguments"));
845 if (arguments != null)
847 for (int i =0; i < arguments.Length; i++)
849 AddArgument(arguments[i],
850 requiredCustomModifiers == null ? null : requiredCustomModifiers[i],
851 optionalCustomModifiers == null ? null : optionalCustomModifiers[i]);
856 [System.Security.SecuritySafeCritical] // auto-generated
857 public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
860 throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized"));
862 if (argument == null)
863 throw new ArgumentNullException("argument");
865 IncrementArgCounts();
867 // Add an argument to the signature. Takes a Type and determines whether it
868 // is one of the primitive types of which we have special knowledge or a more
869 // general class. In the former case, we only add the appropriate short cut encoding,
870 // otherwise we will calculate proper description for the type.
871 AddOneArgTypeHelper(argument, requiredCustomModifiers, optionalCustomModifiers);
874 public void AddSentinel()
876 AddElementType(CorElementType.Sentinel);
879 public override bool Equals(Object obj)
881 if (!(obj is SignatureHelper))
886 SignatureHelper temp = (SignatureHelper)obj;
888 if ( !temp.m_module.Equals(m_module) || temp.m_currSig!=m_currSig || temp.m_sizeLoc!=m_sizeLoc || temp.m_sigDone !=m_sigDone )
893 for (int i=0; i<m_currSig; i++)
895 if (m_signature[i]!=temp.m_signature[i])
901 public override int GetHashCode()
903 // Start the hash code with the hash code of the module and the values of the member variables.
904 int HashCode = m_module.GetHashCode() + m_currSig + m_sizeLoc;
906 // Add one if the sig is done.
910 // Then add the hash code of all the arguments.
911 for (int i=0; i < m_currSig; i++)
912 HashCode += m_signature[i].GetHashCode();
917 public byte[] GetSignature()
919 return GetSignature(false);
922 internal byte[] GetSignature(bool appendEndOfSig)
924 // Chops the internal signature to the appropriate length. Adds the
925 // end token to the signature and marks the signature as finished so that
926 // no further tokens can be added. Return the full signature in a trimmed array.
930 AddElementType(CorElementType.End);
931 SetNumberOfSignatureElements(true);
935 // This case will only happen if the user got the signature through
936 // InternalGetSignature first and then called GetSignature.
937 if (m_signature.Length > m_currSig)
939 byte[] temp = new byte[m_currSig];
940 Array.Copy(m_signature, temp, m_currSig);
947 public override String ToString()
949 StringBuilder sb = new StringBuilder();
950 sb.Append("Length: " + m_currSig + Environment.NewLine);
954 sb.Append("Arguments: " + m_signature[m_sizeLoc] + Environment.NewLine);
958 sb.Append("Field Signature" + Environment.NewLine);
961 sb.Append("Signature: " + Environment.NewLine);
962 for (int i=0; i<=m_currSig; i++)
964 sb.Append(m_signature[i] + " ");
967 sb.Append(Environment.NewLine);
968 return sb.ToString();
974 void _SignatureHelper.GetTypeInfoCount(out uint pcTInfo)
976 throw new NotImplementedException();
979 void _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
981 throw new NotImplementedException();
984 void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
986 throw new NotImplementedException();
989 void _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
991 throw new NotImplementedException();