private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) { EmbeddedSignatureDataEmitter signatureDataEmitter; if (sig.HasEmbeddedSignatureData) { signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); } else { signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; } BlobBuilder memberRefSig = new BlobBuilder(); EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); if (!signatureDataEmitter.Complete) { throw new ArgumentException(); } var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); return(sigBlob); }
/// <summary> /// Gets calling conventions for a standalone ('calli') method signature. /// </summary> public static UnmanagedCallingConventions GetStandaloneMethodSignatureCallingConventions(this MethodSignature signature) { // If calling convention is anything but 'unmanaged', or there's no modifiers, we can bitcast to our enum and we're done. MethodSignatureFlags unmanagedCallconv = signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask; if (unmanagedCallconv != MethodSignatureFlags.UnmanagedCallingConvention) { Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)UnmanagedCallingConventions.Cdecl && (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)UnmanagedCallingConventions.Stdcall && (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)UnmanagedCallingConventions.Thiscall); Debug.Assert(unmanagedCallconv != 0); return((UnmanagedCallingConventions)unmanagedCallconv); } // If calling convention is 'unmanaged', there might be more metadata in the custom modifiers. UnmanagedCallingConventions result = 0; if (signature.HasEmbeddedSignatureData) { foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData()) { if (data.kind != EmbeddedSignatureDataKind.OptionalCustomModifier) { continue; } // We only care about the modifiers for the return type. These will be at the start of // the signature, so will be first in the array of embedded signature data. if (data.index != MethodSignature.IndexOfCustomModifiersOnReturnType) { break; } if (data.type is not MetadataType mdType) { continue; } result = AccumulateCallingConventions(result, mdType); } } // If we haven't found a calling convention in the modifiers, the calling convention is 'unmanaged'. if ((result & UnmanagedCallingConventions.CallingConventionMask) == 0) { result |= GetPlatformDefaultUnmanagedCallingConvention(signature.Context); } return(result); }