1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 // <OWNER>Microsoft</OWNER> 7 // 8 9 namespace System.Reflection.Emit 10 { 11 using System.Text; 12 using System; 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; 19 20 [ClassInterface(ClassInterfaceType.None)] 21 [ComDefaultInterface(typeof(_SignatureHelper))] 22 [System.Runtime.InteropServices.ComVisible(true)] 23 public sealed class SignatureHelper : _SignatureHelper 24 { 25 #region Consts Fields 26 private const int NO_SIZE_IN_SIG = -1; 27 #endregion 28 29 #region Static Members 30 [System.Security.SecuritySafeCritical] // auto-generated GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)31 public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes) 32 { 33 return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null); 34 } 35 36 [System.Security.SecurityCritical] // auto-generated GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam)37 internal static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam) 38 { 39 return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null); 40 } 41 42 [System.Security.SecuritySafeCritical] // auto-generated GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)43 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType) 44 { 45 return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null); 46 } 47 GetMethodSpecSigHelper(Module scope, Type[] inst)48 internal static SignatureHelper GetMethodSpecSigHelper(Module scope, Type[] inst) 49 { 50 SignatureHelper sigHelp = new SignatureHelper(scope, MdSigCallingConvention.GenericInst); 51 sigHelp.AddData(inst.Length); 52 foreach(Type t in inst) 53 sigHelp.AddArgument(t); 54 return sigHelp; 55 } 56 57 [System.Security.SecurityCritical] // auto-generated GetMethodSigHelper( Module scope, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)58 internal static SignatureHelper GetMethodSigHelper( 59 Module scope, CallingConventions callingConvention, 60 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, 61 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 62 { 63 return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers, 64 optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 65 } 66 67 [System.Security.SecurityCritical] // auto-generated GetMethodSigHelper( Module scope, CallingConventions callingConvention, int cGenericParam, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)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) 72 { 73 SignatureHelper sigHelp; 74 MdSigCallingConvention intCall; 75 76 if (returnType == null) 77 { 78 returnType = typeof(void); 79 } 80 81 intCall = MdSigCallingConvention.Default; 82 83 if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) 84 intCall = MdSigCallingConvention.Vararg; 85 86 if (cGenericParam > 0) 87 { 88 intCall |= MdSigCallingConvention.Generic; 89 } 90 91 if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) 92 intCall |= MdSigCallingConvention.HasThis; 93 94 sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType, 95 requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); 96 sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 97 98 return sigHelp; 99 } 100 101 [System.Security.SecuritySafeCritical] // auto-generated GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)102 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType) 103 { 104 SignatureHelper sigHelp; 105 MdSigCallingConvention intCall; 106 107 if (returnType == null) 108 returnType = typeof(void); 109 110 if (unmanagedCallConv == CallingConvention.Cdecl) 111 { 112 intCall = MdSigCallingConvention.C; 113 } 114 else if (unmanagedCallConv == CallingConvention.StdCall || unmanagedCallConv == CallingConvention.Winapi) 115 { 116 intCall = MdSigCallingConvention.StdCall; 117 } 118 else if (unmanagedCallConv == CallingConvention.ThisCall) 119 { 120 intCall = MdSigCallingConvention.ThisCall; 121 } 122 else if (unmanagedCallConv == CallingConvention.FastCall) 123 { 124 intCall = MdSigCallingConvention.FastCall; 125 } 126 else 127 { 128 throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv"); 129 } 130 131 sigHelp = new SignatureHelper(mod, intCall, returnType, null, null); 132 133 return sigHelp; 134 } 135 GetLocalVarSigHelper()136 public static SignatureHelper GetLocalVarSigHelper() 137 { 138 return GetLocalVarSigHelper(null); 139 } 140 GetMethodSigHelper(CallingConventions callingConvention, Type returnType)141 public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType) 142 { 143 return GetMethodSigHelper(null, callingConvention, returnType); 144 } 145 GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)146 public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType) 147 { 148 return GetMethodSigHelper(null, unmanagedCallingConvention, returnType); 149 } 150 GetLocalVarSigHelper(Module mod)151 public static SignatureHelper GetLocalVarSigHelper(Module mod) 152 { 153 return new SignatureHelper(mod, MdSigCallingConvention.LocalSig); 154 } 155 GetFieldSigHelper(Module mod)156 public static SignatureHelper GetFieldSigHelper(Module mod) 157 { 158 return new SignatureHelper(mod, MdSigCallingConvention.Field); 159 } 160 GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)161 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes) 162 { 163 return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null); 164 } 165 GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)166 public static SignatureHelper GetPropertySigHelper(Module mod, 167 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, 168 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 169 { 170 return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, 171 parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 172 } 173 [System.Security.SecuritySafeCritical] // auto-generated GetPropertySigHelper(Module mod, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)174 public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, 175 Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, 176 Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 177 { 178 SignatureHelper sigHelp; 179 180 if (returnType == null) 181 { 182 returnType = typeof(void); 183 } 184 185 MdSigCallingConvention intCall = MdSigCallingConvention.Property; 186 187 if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) 188 intCall |= MdSigCallingConvention.HasThis; 189 190 sigHelp = new SignatureHelper(mod, intCall, 191 returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); 192 sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 193 194 return sigHelp; 195 } 196 197 [System.Security.SecurityCritical] // auto-generated GetTypeSigToken(Module mod, Type type)198 internal static SignatureHelper GetTypeSigToken(Module mod, Type type) 199 { 200 if (mod == null) 201 throw new ArgumentNullException("module"); 202 203 if (type == null) 204 throw new ArgumentNullException("type"); 205 206 return new SignatureHelper(mod, type); 207 } 208 #endregion 209 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 217 #endregion 218 219 #region Constructor SignatureHelper(Module mod, MdSigCallingConvention callingConvention)220 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention) 221 { 222 // Use this constructor to instantiate a local var sig or Field where return type is not applied. 223 Init(mod, callingConvention); 224 } 225 226 [System.Security.SecurityCritical] // auto-generated SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters, Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)227 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters, 228 Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) 229 { 230 // Use this constructor to instantiate a any signatures that will require a return type. 231 Init(mod, callingConvention, cGenericParameters); 232 233 if (callingConvention == MdSigCallingConvention.Field) 234 throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig")); 235 236 AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers); 237 } 238 239 [System.Security.SecurityCritical] // auto-generated SignatureHelper(Module mod, MdSigCallingConvention callingConvention, Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)240 private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, 241 Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) 242 : this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers) 243 { 244 } 245 246 [System.Security.SecurityCritical] // auto-generated SignatureHelper(Module mod, Type type)247 private SignatureHelper(Module mod, Type type) 248 { 249 Init(mod); 250 251 AddOneArgTypeHelper(type); 252 } 253 Init(Module mod)254 private void Init(Module mod) 255 { 256 m_signature = new byte[32]; 257 m_currSig = 0; 258 m_module = mod as ModuleBuilder; 259 m_argCount = 0; 260 m_sigDone = false; 261 m_sizeLoc = NO_SIZE_IN_SIG; 262 263 if (m_module == null && mod != null) 264 throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder")); 265 } 266 Init(Module mod, MdSigCallingConvention callingConvention)267 private void Init(Module mod, MdSigCallingConvention callingConvention) 268 { 269 Init(mod, callingConvention, 0); 270 } 271 Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam)272 private void Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam) 273 { 274 Init(mod); 275 276 AddData((byte)callingConvention); 277 278 if (callingConvention == MdSigCallingConvention.Field || 279 callingConvention == MdSigCallingConvention.GenericInst) 280 { 281 m_sizeLoc = NO_SIZE_IN_SIG; 282 } 283 else 284 { 285 if (cGenericParam > 0) 286 AddData(cGenericParam); 287 288 m_sizeLoc = m_currSig++; 289 } 290 } 291 292 #endregion 293 294 #region Private Members 295 [System.Security.SecurityCritical] // auto-generated AddOneArgTypeHelper(Type argument, bool pinned)296 private void AddOneArgTypeHelper(Type argument, bool pinned) 297 { 298 if (pinned) 299 AddElementType(CorElementType.Pinned); 300 301 AddOneArgTypeHelper(argument); 302 } 303 304 [System.Security.SecurityCritical] // auto-generated AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)305 private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) 306 { 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. 309 310 Contract.Requires(clsArgument != null); 311 Contract.Requires((optionalCustomModifiers == null && requiredCustomModifiers == null) || !clsArgument.ContainsGenericParameters); 312 313 if (optionalCustomModifiers != null) 314 { 315 for (int i = 0; i < optionalCustomModifiers.Length; i++) 316 { 317 Type t = optionalCustomModifiers[i]; 318 319 if (t == null) 320 throw new ArgumentNullException("optionalCustomModifiers"); 321 322 if (t.HasElementType) 323 throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "optionalCustomModifiers"); 324 325 if (t.ContainsGenericParameters) 326 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "optionalCustomModifiers"); 327 328 AddElementType(CorElementType.CModOpt); 329 330 int token = m_module.GetTypeToken(t).Token; 331 Contract.Assert(!MetadataToken.IsNullToken(token)); 332 AddToken(token); 333 } 334 } 335 336 if (requiredCustomModifiers != null) 337 { 338 for (int i = 0; i < requiredCustomModifiers.Length; i++) 339 { 340 Type t = requiredCustomModifiers[i]; 341 342 if (t == null) 343 throw new ArgumentNullException("requiredCustomModifiers"); 344 345 if (t.HasElementType) 346 throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "requiredCustomModifiers"); 347 348 if (t.ContainsGenericParameters) 349 throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "requiredCustomModifiers"); 350 351 AddElementType(CorElementType.CModReqd); 352 353 int token = m_module.GetTypeToken(t).Token; 354 Contract.Assert(!MetadataToken.IsNullToken(token)); 355 AddToken(token); 356 } 357 } 358 359 AddOneArgTypeHelper(clsArgument); 360 } 361 362 [System.Security.SecurityCritical] // auto-generated AddOneArgTypeHelper(Type clsArgument)363 private void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); } 364 [System.Security.SecurityCritical] // auto-generated AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst)365 private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst) 366 { 367 if (clsArgument.IsGenericParameter) 368 { 369 if (clsArgument.DeclaringMethod != null) 370 AddElementType(CorElementType.MVar); 371 else 372 AddElementType(CorElementType.Var); 373 374 AddData(clsArgument.GenericParameterPosition); 375 } 376 else if (clsArgument.IsGenericType && (!clsArgument.IsGenericTypeDefinition || !lastWasGenericInst)) 377 { 378 AddElementType(CorElementType.GenericInst); 379 380 AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true); 381 382 Type[] args = clsArgument.GetGenericArguments(); 383 384 AddData(args.Length); 385 386 foreach (Type t in args) 387 AddOneArgTypeHelper(t); 388 } 389 else if (clsArgument is TypeBuilder) 390 { 391 TypeBuilder clsBuilder = (TypeBuilder)clsArgument; 392 TypeToken tkType; 393 394 if (clsBuilder.Module.Equals(m_module)) 395 { 396 tkType = clsBuilder.TypeToken; 397 } 398 else 399 { 400 tkType = m_module.GetTypeToken(clsArgument); 401 } 402 403 if (clsArgument.IsValueType) 404 { 405 InternalAddTypeToken(tkType, CorElementType.ValueType); 406 } 407 else 408 { 409 InternalAddTypeToken(tkType, CorElementType.Class); 410 } 411 } 412 else if (clsArgument is EnumBuilder) 413 { 414 TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder; 415 TypeToken tkType; 416 417 if (clsBuilder.Module.Equals(m_module)) 418 { 419 tkType = clsBuilder.TypeToken; 420 } 421 else 422 { 423 tkType = m_module.GetTypeToken(clsArgument); 424 } 425 426 if (clsArgument.IsValueType) 427 { 428 InternalAddTypeToken(tkType, CorElementType.ValueType); 429 } 430 else 431 { 432 InternalAddTypeToken(tkType, CorElementType.Class); 433 } 434 } 435 else if (clsArgument.IsByRef) 436 { 437 AddElementType(CorElementType.ByRef); 438 clsArgument = clsArgument.GetElementType(); 439 AddOneArgTypeHelper(clsArgument); 440 } 441 else if (clsArgument.IsPointer) 442 { 443 AddElementType(CorElementType.Ptr); 444 AddOneArgTypeHelper(clsArgument.GetElementType()); 445 } 446 else if (clsArgument.IsArray) 447 { 448 if (clsArgument.IsSzArray) 449 { 450 AddElementType(CorElementType.SzArray); 451 452 AddOneArgTypeHelper(clsArgument.GetElementType()); 453 } 454 else 455 { 456 AddElementType(CorElementType.Array); 457 458 AddOneArgTypeHelper(clsArgument.GetElementType()); 459 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++) 466 AddData(0); 467 } 468 } 469 else 470 { 471 CorElementType type = CorElementType.Max; 472 473 if (clsArgument is RuntimeType) 474 { 475 type = RuntimeTypeHandle.GetCorElementType((RuntimeType)clsArgument); 476 477 //GetCorElementType returns CorElementType.Class for both object and string 478 if (type == CorElementType.Class) 479 { 480 if (clsArgument == typeof(object)) 481 type = CorElementType.Object; 482 else if (clsArgument == typeof(string)) 483 type = CorElementType.String; 484 } 485 } 486 487 if (IsSimpleType(type)) 488 { 489 AddElementType(type); 490 } 491 else if (m_module == null) 492 { 493 InternalAddRuntimeType(clsArgument); 494 } 495 else if (clsArgument.IsValueType) 496 { 497 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.ValueType); 498 } 499 else 500 { 501 InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.Class); 502 } 503 } 504 } 505 AddData(int data)506 private void AddData(int data) 507 { 508 // A managed representation of CorSigCompressData; 509 510 if (m_currSig + 4 > m_signature.Length) 511 { 512 m_signature = ExpandArray(m_signature); 513 } 514 515 if (data <= 0x7F) 516 { 517 m_signature[m_currSig++] = (byte)(data & 0xFF); 518 } 519 else if (data <= 0x3FFF) 520 { 521 m_signature[m_currSig++] = (byte)((data >>8) | 0x80); 522 m_signature[m_currSig++] = (byte)(data & 0xFF); 523 } 524 else if (data <= 0x1FFFFFFF) 525 { 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); 530 } 531 else 532 { 533 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); 534 } 535 536 } 537 AddData(uint data)538 private void AddData(uint data) 539 { 540 if (m_currSig + 4 > m_signature.Length) 541 { 542 m_signature = ExpandArray(m_signature); 543 } 544 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); 549 } 550 AddData(ulong data)551 private void AddData(ulong data) 552 { 553 if (m_currSig + 8 > m_signature.Length) 554 { 555 m_signature = ExpandArray(m_signature); 556 } 557 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); 566 } 567 AddElementType(CorElementType cvt)568 private void AddElementType(CorElementType cvt) 569 { 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); 573 574 m_signature[m_currSig++] = (byte)cvt; 575 } 576 AddToken(int token)577 private void AddToken(int token) 578 { 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. 582 583 int rid = (token & 0x00FFFFFF); //This is RidFromToken; 584 MetadataTokenType type = (MetadataTokenType)(token & unchecked((int)0xFF000000)); //This is TypeFromToken; 585 586 if (rid > 0x3FFFFFF) 587 { 588 // token is too big to be compressed 589 throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); 590 } 591 592 rid = (rid << 2); 593 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) 598 { 599 //if type is mdtTypeRef 600 rid|=0x1; 601 } 602 else if (type == MetadataTokenType.TypeSpec) 603 { 604 //if type is mdtTypeSpec 605 rid|=0x2; 606 } 607 608 AddData(rid); 609 } 610 InternalAddTypeToken(TypeToken clsToken, CorElementType CorType)611 private void InternalAddTypeToken(TypeToken clsToken, CorElementType CorType) 612 { 613 // Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType 614 AddElementType(CorType); 615 AddToken(clsToken.Token); 616 } 617 618 [System.Security.SecurityCritical] // auto-generated InternalAddRuntimeType(Type type)619 private unsafe void InternalAddRuntimeType(Type type) 620 { 621 // Add a runtime type into the signature. 622 623 AddElementType(CorElementType.Internal); 624 625 IntPtr handle = type.GetTypeHandleInternal().Value; 626 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)). 630 631 if (m_currSig + sizeof(void*) > m_signature.Length) 632 m_signature = ExpandArray(m_signature); 633 634 byte *phandle = (byte*)&handle; 635 for (int i = 0; i < sizeof(void*); i++) 636 m_signature[m_currSig++] = phandle[i]; 637 } 638 ExpandArray(byte[] inArray)639 private byte[] ExpandArray(byte[] inArray) 640 { 641 // Expand the signature buffer size 642 return ExpandArray(inArray, inArray.Length * 2); 643 } 644 ExpandArray(byte[] inArray, int requiredLength)645 private byte[] ExpandArray(byte[] inArray, int requiredLength) 646 { 647 // Expand the signature buffer size 648 649 if (requiredLength < inArray.Length) 650 requiredLength = inArray.Length*2; 651 652 byte[] outArray = new byte[requiredLength]; 653 Array.Copy(inArray, outArray, inArray.Length); 654 return outArray; 655 } 656 IncrementArgCounts()657 private void IncrementArgCounts() 658 { 659 if (m_sizeLoc == NO_SIZE_IN_SIG) 660 { 661 //We don't have a size if this is a field. 662 return; 663 } 664 665 m_argCount++; 666 } 667 SetNumberOfSignatureElements(bool forceCopy)668 private void SetNumberOfSignatureElements(bool forceCopy) 669 { 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. 678 679 byte[] temp; 680 int newSigSize; 681 int currSigHolder = m_currSig; 682 683 if (m_sizeLoc == NO_SIZE_IN_SIG) 684 return; 685 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) 689 { 690 m_signature[m_sizeLoc] = (byte)m_argCount; 691 return; 692 } 693 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 696 //new allocation. 697 if (m_argCount < 0x80) 698 { 699 newSigSize = 1; 700 } 701 else if (m_argCount < 0x4000) 702 { 703 newSigSize = 2; 704 } 705 else 706 { 707 newSigSize = 4; 708 } 709 710 //Allocate the new array. 711 temp = new byte[m_currSig + newSigSize - 1]; 712 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)); 718 m_signature = temp; 719 720 //Use the AddData method to add the number of elements appropriately compressed. 721 m_currSig = m_sizeLoc; 722 AddData(m_argCount); 723 m_currSig = currSigHolder + (newSigSize - 1); 724 } 725 726 #endregion 727 728 #region Internal Members 729 internal int ArgumentCount 730 { 731 get 732 { 733 return m_argCount; 734 } 735 } 736 IsSimpleType(CorElementType type)737 internal static bool IsSimpleType(CorElementType type) 738 { 739 if (type <= CorElementType.String) 740 return true; 741 742 if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object) 743 return true; 744 745 return false; 746 } 747 InternalGetSignature(out int length)748 internal byte[] InternalGetSignature(out int length) 749 { 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 753 // to not copy it. 754 // 755 // param length : an out param indicating the length of the array. 756 // return : A reference to the internal ubyte array. 757 758 if (!m_sigDone) 759 { 760 m_sigDone = true; 761 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); 766 } 767 768 length = m_currSig; 769 return m_signature; 770 } 771 772 773 774 InternalGetSignatureArray()775 internal byte[] InternalGetSignatureArray() 776 { 777 int argCount = m_argCount; 778 int currSigLength = m_currSig; 779 int newSigSize = currSigLength; 780 781 //Allocate the new array. 782 if (argCount < 0x7F) 783 newSigSize += 1; 784 else if (argCount < 0x3FFF) 785 newSigSize += 2; 786 else 787 newSigSize += 4; 788 byte[] temp = new byte[newSigSize]; 789 790 // copy the sig 791 int sigCopyIndex = 0; 792 // calling convention 793 temp[sigCopyIndex++] = m_signature[0]; 794 // arg size 795 if (argCount <= 0x7F) 796 temp[sigCopyIndex++] = (byte)(argCount & 0xFF); 797 else if (argCount <= 0x3FFF) 798 { 799 temp[sigCopyIndex++] = (byte)((argCount >>8) | 0x80); 800 temp[sigCopyIndex++] = (byte)(argCount & 0xFF); 801 } 802 else if (argCount <= 0x1FFFFFFF) 803 { 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); 808 } 809 else 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; 815 816 return temp; 817 } 818 819 #endregion 820 821 #region Public Methods AddArgument(Type clsArgument)822 public void AddArgument(Type clsArgument) 823 { 824 AddArgument(clsArgument, null, null); 825 } 826 827 [System.Security.SecuritySafeCritical] // auto-generated AddArgument(Type argument, bool pinned)828 public void AddArgument(Type argument, bool pinned) 829 { 830 if (argument == null) 831 throw new ArgumentNullException("argument"); 832 833 IncrementArgCounts(); 834 AddOneArgTypeHelper(argument, pinned); 835 } 836 AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)837 public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) 838 { 839 if (requiredCustomModifiers != null && (arguments == null || requiredCustomModifiers.Length != arguments.Length)) 840 throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "requiredCustomModifiers", "arguments")); 841 842 if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length)) 843 throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "optionalCustomModifiers", "arguments")); 844 845 if (arguments != null) 846 { 847 for (int i =0; i < arguments.Length; i++) 848 { 849 AddArgument(arguments[i], 850 requiredCustomModifiers == null ? null : requiredCustomModifiers[i], 851 optionalCustomModifiers == null ? null : optionalCustomModifiers[i]); 852 } 853 } 854 } 855 856 [System.Security.SecuritySafeCritical] // auto-generated AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)857 public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) 858 { 859 if (m_sigDone) 860 throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized")); 861 862 if (argument == null) 863 throw new ArgumentNullException("argument"); 864 865 IncrementArgCounts(); 866 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); 872 } 873 AddSentinel()874 public void AddSentinel() 875 { 876 AddElementType(CorElementType.Sentinel); 877 } 878 Equals(Object obj)879 public override bool Equals(Object obj) 880 { 881 if (!(obj is SignatureHelper)) 882 { 883 return false; 884 } 885 886 SignatureHelper temp = (SignatureHelper)obj; 887 888 if ( !temp.m_module.Equals(m_module) || temp.m_currSig!=m_currSig || temp.m_sizeLoc!=m_sizeLoc || temp.m_sigDone !=m_sigDone ) 889 { 890 return false; 891 } 892 893 for (int i=0; i<m_currSig; i++) 894 { 895 if (m_signature[i]!=temp.m_signature[i]) 896 return false; 897 } 898 return true; 899 } 900 GetHashCode()901 public override int GetHashCode() 902 { 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; 905 906 // Add one if the sig is done. 907 if (m_sigDone) 908 HashCode += 1; 909 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(); 913 914 return HashCode; 915 } 916 GetSignature()917 public byte[] GetSignature() 918 { 919 return GetSignature(false); 920 } 921 GetSignature(bool appendEndOfSig)922 internal byte[] GetSignature(bool appendEndOfSig) 923 { 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. 927 if (!m_sigDone) 928 { 929 if (appendEndOfSig) 930 AddElementType(CorElementType.End); 931 SetNumberOfSignatureElements(true); 932 m_sigDone = true; 933 } 934 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) 938 { 939 byte[] temp = new byte[m_currSig]; 940 Array.Copy(m_signature, temp, m_currSig); 941 m_signature = temp; 942 } 943 944 return m_signature; 945 } 946 ToString()947 public override String ToString() 948 { 949 StringBuilder sb = new StringBuilder(); 950 sb.Append("Length: " + m_currSig + Environment.NewLine); 951 952 if (m_sizeLoc != -1) 953 { 954 sb.Append("Arguments: " + m_signature[m_sizeLoc] + Environment.NewLine); 955 } 956 else 957 { 958 sb.Append("Field Signature" + Environment.NewLine); 959 } 960 961 sb.Append("Signature: " + Environment.NewLine); 962 for (int i=0; i<=m_currSig; i++) 963 { 964 sb.Append(m_signature[i] + " "); 965 } 966 967 sb.Append(Environment.NewLine); 968 return sb.ToString(); 969 } 970 971 #endregion 972 973 #if !FEATURE_CORECLR _SignatureHelper.GetTypeInfoCount(out uint pcTInfo)974 void _SignatureHelper.GetTypeInfoCount(out uint pcTInfo) 975 { 976 throw new NotImplementedException(); 977 } 978 _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)979 void _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) 980 { 981 throw new NotImplementedException(); 982 } 983 _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)984 void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) 985 { 986 throw new NotImplementedException(); 987 } 988 _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)989 void _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) 990 { 991 throw new NotImplementedException(); 992 } 993 #endif 994 995 } 996 } 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022