void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig) { BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); int genericParameterCount = sig.GenericParameterCount; bool isInstanceMethod = !sig.IsStatic; SignatureCallingConvention sigCallingConvention = SignatureCallingConvention.Default; switch (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.CallingConventionVarargs: sigCallingConvention = SignatureCallingConvention.VarArgs; break; case MethodSignatureFlags.UnmanagedCallingConventionCdecl: sigCallingConvention = SignatureCallingConvention.CDecl; break; case MethodSignatureFlags.UnmanagedCallingConventionStdCall: sigCallingConvention = SignatureCallingConvention.StdCall; break; case MethodSignatureFlags.UnmanagedCallingConventionThisCall: sigCallingConvention = SignatureCallingConvention.ThisCall; break; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); // TODO Process custom modifiers in some way EncodeType(signatureBuilder, sig.ReturnType); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i]); } }
/// <summary> /// Starts a function pointer signature. /// </summary> /// <param name="convention">Calling convention.</param> /// <param name="attributes">Function pointer attributes.</param> /// <param name="genericParameterCount">Generic parameter count.</param> /// <exception cref="ArgumentException"><paramref name="attributes"/> is invalid.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="genericParameterCount"/> is not in range [0, 0xffff].</exception> public MethodSignatureEncoder FunctionPointer( SignatureCallingConvention convention = SignatureCallingConvention.Default, FunctionPointerAttributes attributes = FunctionPointerAttributes.None, int genericParameterCount = 0) { // Spec: // The EXPLICITTHIS (0x40) bit can be set only in signatures for function pointers. // If EXPLICITTHIS (0x40) in the signature is set, then HASTHIS (0x20) shall also be set. if (attributes != FunctionPointerAttributes.None && attributes != FunctionPointerAttributes.HasThis && attributes != FunctionPointerAttributes.HasExplicitThis) { throw new ArgumentException(SR.InvalidSignature, nameof(attributes)); } if (unchecked ((uint)genericParameterCount) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(genericParameterCount)); } Builder.WriteByte((byte)SignatureTypeCode.FunctionPointer); Builder.WriteByte(new SignatureHeader(SignatureKind.Method, convention, (SignatureAttributes)attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return(new MethodSignatureEncoder(Builder, hasVarArgs: convention == SignatureCallingConvention.VarArgs)); }
private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData) { SignatureHeader header = _reader.ReadSignatureHeader(); MethodSignatureFlags flags = 0; SignatureCallingConvention signatureCallConv = header.CallingConvention; if (signatureCallConv != SignatureCallingConvention.Default) { // Verify that it is safe to convert CallingConvention to MethodSignatureFlags via a simple cast Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)SignatureCallingConvention.CDecl); Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)SignatureCallingConvention.StdCall); Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)SignatureCallingConvention.ThisCall); Debug.Assert((int)MethodSignatureFlags.CallingConventionVarargs == (int)SignatureCallingConvention.VarArgs); Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConvention == (int)SignatureCallingConvention.Unmanaged); flags = (MethodSignatureFlags)signatureCallConv; } if (!header.IsInstance) { flags |= MethodSignatureFlags.Static; } int arity = header.IsGeneric ? _reader.ReadCompressedInteger() : 0; int count = _reader.ReadCompressedInteger(); TypeDesc returnType = ParseType(); TypeDesc[] parameters; if (count > 0) { // Get all of the parameters. parameters = new TypeDesc[count]; for (int i = 0; i < count; i++) { parameters[i] = ParseType(); } } else { parameters = TypeDesc.EmptyTypes; } EmbeddedSignatureData[] embeddedSignatureDataArray = (_embeddedSignatureDataList == null || _embeddedSignatureDataList.Count == 0 || skipEmbeddedSignatureData) ? null : _embeddedSignatureDataList.ToArray(); if (_resolutionFailure == null) { return(new MethodSignature(flags, arity, returnType, parameters, embeddedSignatureDataArray)); } else { return(null); } }
internal static CallingConvention FromSignatureConvention(this SignatureCallingConvention convention) { if (!convention.IsValid()) { throw new UnsupportedSignatureContent(); } return((CallingConvention)(convention & SignatureCallingConventionMask)); }
private static string GetC99CallConv(SignatureCallingConvention callConv) { return(callConv switch { SignatureCallingConvention.CDecl => "DNNE_CALLTYPE_CDECL", SignatureCallingConvention.StdCall => "DNNE_CALLTYPE_STDCALL", SignatureCallingConvention.ThisCall => "DNNE_CALLTYPE_THISCALL", SignatureCallingConvention.FastCall => "DNNE_CALLTYPE_FASTCALL", SignatureCallingConvention.Unmanaged => "DNNE_CALLTYPE", _ => throw new NotSupportedException($"Unknown CallingConvention: {callConv}"), });
internal static CallingConvention FromSignatureConvention(this SignatureCallingConvention convention, bool throwOnInvalidConvention = false) { var callingConvention = (CallingConvention)(convention & SignatureCallingConventionMask); if (throwOnInvalidConvention && callingConvention != (CallingConvention)convention) { throw new UnsupportedSignatureContent(); } return(callingConvention); }
public FunctionPointerType(MetadataModule module, SignatureCallingConvention callingConvention, IType returnType, bool returnIsRefReadOnly, ImmutableArray <IType> parameterTypes, ImmutableArray <ReferenceKind> parameterReferenceKinds) { this.module = module; this.CallingConvention = callingConvention; this.ReturnType = returnType; this.ReturnIsRefReadOnly = returnIsRefReadOnly; this.ParameterTypes = parameterTypes; this.ParameterReferenceKinds = parameterReferenceKinds; Debug.Assert(parameterTypes.Length == parameterReferenceKinds.Length); }
public MethodSignature ParseMethodSignature() { SignatureHeader header = _reader.ReadSignatureHeader(); MethodSignatureFlags flags = 0; SignatureCallingConvention signatureCallConv = header.CallingConvention; if (signatureCallConv != SignatureCallingConvention.Default) { // Verify that it is safe to convert CallingConvention to MethodSignatureFlags via a simple cast Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)SignatureCallingConvention.CDecl); Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)SignatureCallingConvention.StdCall); Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)SignatureCallingConvention.ThisCall); // Vararg methods are not supported in .NET Core if (signatureCallConv == SignatureCallingConvention.VarArgs) { throw new TypeSystemException.BadImageFormatException(); } flags = (MethodSignatureFlags)signatureCallConv; } if (!header.IsInstance) { flags |= MethodSignatureFlags.Static; } int arity = header.IsGeneric ? _reader.ReadCompressedInteger() : 0; int count = _reader.ReadCompressedInteger(); TypeDesc returnType = ParseType(); TypeDesc[] parameters; if (count > 0) { // Get all of the parameters. parameters = new TypeDesc[count]; for (int i = 0; i < count; i++) { parameters[i] = ParseType(); } } else { parameters = TypeDesc.EmptyTypes; } return(new MethodSignature(flags, arity, returnType, parameters)); }
public static SignatureCallingConvention ConvertCallingConvention(CallingConventions callingConvention) { // TODO: incorrect / draft implementation // See https://stackoverflow.com/questions/54632913/how-to-convert-callingconventions-into-signaturecallingconvention //if (callingConvention.HasFlag(CallingConventions.Any)) // result |= SignatureCallingConvention.StdCall | SignatureCallingConvention.VarArgs; //if (callingConvention.HasFlag(CallingConventions.ExplicitThis)) // result = 0x40; //else if (callingConvention.HasFlag(CallingConventions.HasThis)) // result = 0x20; SignatureCallingConvention result = 0; //if(callingConvention.HasFlag(CallingConventions.HasThis)) // result |= SignatureCallingConvention.ThisCall; //if (callingConvention.HasFlag(CallingConventions.Standard)) // result |= SignatureCallingConvention.StdCall; if (callingConvention.HasFlag(CallingConventions.VarArgs)) { result |= SignatureCallingConvention.VarArgs; } return(result); /* * var result = SignatureCallingConvention.Default; * * if (callingConvention.HasFlag(CallingConventions.Any)) * result |= SignatureCallingConvention.StdCall | SignatureCallingConvention.VarArgs; * * if (callingConvention.HasFlag(CallingConventions.ExplicitThis)) * throw new Exception("Unknown Calling Convention (ExplicitThis)"); * * if (callingConvention.HasFlag(CallingConventions.HasThis)) * result |= SignatureCallingConvention.ThisCall; * * if (callingConvention.HasFlag(CallingConventions.Standard)) * result |= SignatureCallingConvention.StdCall; * * if (callingConvention.HasFlag(CallingConventions.VarArgs)) * result |= SignatureCallingConvention.VarArgs; * * return result; */ }
internal static string GetCallingConvention(SignatureCallingConvention callingConvention) { if (callingConvention == SignatureCallingConvention.Default) { return("managed"); } if (callingConvention == SignatureCallingConvention.Unmanaged) { return("unmanaged"); } return($"unmanaged[{callingConvention}]"); }
private void EmitFunctionPointerTypeSignature(FunctionPointerType type, SignatureContext context) { SignatureCallingConvention callingConvention = (SignatureCallingConvention)(type.Signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask); SignatureAttributes callingConventionAttributes = ((type.Signature.Flags & MethodSignatureFlags.Static) != 0 ? SignatureAttributes.None : SignatureAttributes.Instance); EmitElementType(CorElementType.ELEMENT_TYPE_FNPTR); EmitUInt((uint)((byte)callingConvention | (byte)callingConventionAttributes)); EmitUInt((uint)type.Signature.Length); EmitTypeSignature(type.Signature.ReturnType, context); for (int argIndex = 0; argIndex < type.Signature.Length; argIndex++) { EmitTypeSignature(type.Signature[argIndex], context); } }
private void WriteUnmanagedCallConv(SignatureCallingConvention callConv) { switch (callConv) { case SignatureCallingConvention.Default: case SignatureCallingConvention.Unmanaged: { // nothing to print here break; } case SignatureCallingConvention.CDecl: { Append("Cdecl"); break; } case SignatureCallingConvention.StdCall: { Append("Stdcall"); break; } case SignatureCallingConvention.ThisCall: { Append("Thiscall"); break; } case SignatureCallingConvention.FastCall: { Append("Fastcall"); break; } default: { var name = callConv.ToString(); Append(name.Substring(0, 1)); Append(name.Substring(1).ToLower()); break; } } }
void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); int genericParameterCount = sig.GenericParameterCount; bool isInstanceMethod = !sig.IsStatic; SignatureCallingConvention sigCallingConvention = SignatureCallingConvention.Default; switch (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.CallingConventionVarargs: sigCallingConvention = SignatureCallingConvention.VarArgs; break; case MethodSignatureFlags.UnmanagedCallingConventionCdecl: sigCallingConvention = SignatureCallingConvention.CDecl; break; case MethodSignatureFlags.UnmanagedCallingConventionStdCall: sigCallingConvention = SignatureCallingConvention.StdCall; break; case MethodSignatureFlags.UnmanagedCallingConventionThisCall: sigCallingConvention = SignatureCallingConvention.ThisCall; break; case MethodSignatureFlags.UnmanagedCallingConvention: // [TODO] sigCallingConvention = SignatureCallingConvention.Unmanaged; sigCallingConvention = (SignatureCallingConvention)9; break; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); EncodeType(signatureBuilder, sig.ReturnType, signatureDataEmitter); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i], signatureDataEmitter); } signatureDataEmitter.Pop(); }
public MethodSignatureEncoder MethodSignature( SignatureCallingConvention convention = SignatureCallingConvention.Default, int genericParameterCount = 0, bool isInstanceMethod = false) { // TODO: arg validation var attributes = (genericParameterCount != 0 ? SignatureAttributes.Generic : 0) | (isInstanceMethod ? SignatureAttributes.Instance : 0); Builder.WriteByte(SignatureHeader(SignatureKind.Method, convention, attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return(new MethodSignatureEncoder(Builder, isVarArg: convention == SignatureCallingConvention.VarArgs)); }
public MethodSignatureEncoder MethodSignature( SignatureCallingConvention convention = SignatureCallingConvention.Default, int genericParameterCount = 0, bool isInstanceMethod = false) { // TODO: arg validation var attributes = (genericParameterCount != 0 ? SignatureAttributes.Generic : 0) | (isInstanceMethod ? SignatureAttributes.Instance : 0); Builder.WriteByte(SignatureHeader(SignatureKind.Method, convention, attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return new MethodSignatureEncoder(Builder, isVarArg: convention == SignatureCallingConvention.VarArgs); }
/// <summary> /// Encodes Method Signature blob. /// </summary> /// <param name="convention">Calling convention.</param> /// <param name="genericParameterCount">Number of generic parameters.</param> /// <param name="isInstanceMethod">True to encode an instance method signature, false to encode a static method signature.</param> /// <returns>An Encoder of the rest of the signature including return value and parameters.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="genericParameterCount"/> is not in range [0, 0xffff].</exception> public MethodSignatureEncoder MethodSignature( SignatureCallingConvention convention = SignatureCallingConvention.Default, int genericParameterCount = 0, bool isInstanceMethod = false) { if (unchecked ((uint)genericParameterCount) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(genericParameterCount)); } var attributes = (genericParameterCount != 0 ? SignatureAttributes.Generic : 0) | (isInstanceMethod ? SignatureAttributes.Instance : 0); Builder.WriteByte(new SignatureHeader(SignatureKind.Method, convention, attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return(new MethodSignatureEncoder(Builder, hasVarArgs: convention == SignatureCallingConvention.VarArgs)); }
public MethodSignatureEncoder MethodSignature( SignatureCallingConvention convention = SignatureCallingConvention.Default, int genericParameterCount = 0, bool isInstanceMethod = false) { if (unchecked((uint)genericParameterCount) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(genericParameterCount)); } var attributes = (genericParameterCount != 0 ? SignatureAttributes.Generic : 0) | (isInstanceMethod ? SignatureAttributes.Instance : 0); Builder.WriteByte(new SignatureHeader(SignatureKind.Method, convention, attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return new MethodSignatureEncoder(Builder, hasVarArgs: convention == SignatureCallingConvention.VarArgs); }
public MethodSignatureEncoder FunctionPointer(SignatureCallingConvention convention, FunctionPointerAttributes attributes, int genericParameterCount) { // Spec: // The EXPLICITTHIS (0x40) bit can be set only in signatures for function pointers. // If EXPLICITTHIS (0x40) in the signature is set, then HASTHIS (0x20) shall also be set. if (attributes != FunctionPointerAttributes.None && attributes != FunctionPointerAttributes.HasThis && attributes != FunctionPointerAttributes.HasExplicitThis) { throw new ArgumentException(nameof(attributes)); } Builder.WriteByte((byte)SignatureTypeCode.FunctionPointer); Builder.WriteByte(BlobEncoder.SignatureHeader(SignatureKind.Method, convention, (SignatureAttributes)attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return(new MethodSignatureEncoder(Builder, isVarArg: convention == SignatureCallingConvention.VarArgs)); }
public SignatureHeader(SignatureKind kind, SignatureCallingConvention convention, SignatureAttributes attributes) : this((byte)((int)kind | (int)convention | (int)attributes)) { }
// TOOD: add ctor to SignatureHeader internal static SignatureHeader SignatureHeader(SignatureKind kind, SignatureCallingConvention convention, SignatureAttributes attributes) { return new SignatureHeader((byte)((int)kind | (int)convention | (int)attributes)); }
// TOOD: add ctor to SignatureHeader internal static SignatureHeader SignatureHeader(SignatureKind kind, SignatureCallingConvention convention, SignatureAttributes attributes) { return(new SignatureHeader((byte)((int)kind | (int)convention | (int)attributes))); }
internal static bool IsValid(this SignatureCallingConvention convention) => convention <= SignatureCallingConvention.VarArgs || convention == SignatureCallingConvention.Unmanaged;
/// <summary> /// Starts a function pointer signature. /// </summary> /// <param name="convention">Calling convention.</param> /// <param name="attributes">Function pointer attributes.</param> /// <param name="genericParameterCount">Generic parameter count.</param> /// <exception cref="ArgumentException"><paramref name="attributes"/> is invalid.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="genericParameterCount"/> is not in range [0, 0xffff].</exception> public MethodSignatureEncoder FunctionPointer( SignatureCallingConvention convention = SignatureCallingConvention.Default, FunctionPointerAttributes attributes = FunctionPointerAttributes.None, int genericParameterCount = 0) { // Spec: // The EXPLICITTHIS (0x40) bit can be set only in signatures for function pointers. // If EXPLICITTHIS (0x40) in the signature is set, then HASTHIS (0x20) shall also be set. if (attributes != FunctionPointerAttributes.None && attributes != FunctionPointerAttributes.HasThis && attributes != FunctionPointerAttributes.HasExplicitThis) { throw new ArgumentException(SR.InvalidSignature, nameof(attributes)); } if (unchecked((uint)genericParameterCount) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(genericParameterCount)); } Builder.WriteByte((byte)SignatureTypeCode.FunctionPointer); Builder.WriteByte(new SignatureHeader(SignatureKind.Method, convention, (SignatureAttributes)attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return new MethodSignatureEncoder(Builder, hasVarArgs: convention == SignatureCallingConvention.VarArgs); }
public MethodSignatureEncoder FunctionPointer(SignatureCallingConvention convention, FunctionPointerAttributes attributes, int genericParameterCount) { // Spec: // The EXPLICITTHIS (0x40) bit can be set only in signatures for function pointers. // If EXPLICITTHIS (0x40) in the signature is set, then HASTHIS (0x20) shall also be set. if (attributes != FunctionPointerAttributes.None && attributes != FunctionPointerAttributes.HasThis && attributes != FunctionPointerAttributes.HasExplicitThis) { throw new ArgumentException(nameof(attributes)); } Builder.WriteByte((byte)SignatureTypeCode.FunctionPointer); Builder.WriteByte(BlobEncoder.SignatureHeader(SignatureKind.Method, convention, (SignatureAttributes)attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return new MethodSignatureEncoder(Builder, isVarArg: convention == SignatureCallingConvention.VarArgs); }