Пример #1
0
        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]);
            }
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        internal static CallingConvention FromSignatureConvention(this SignatureCallingConvention convention)
        {
            if (!convention.IsValid())
            {
                throw new UnsupportedSignatureContent();
            }

            return((CallingConvention)(convention & SignatureCallingConventionMask));
        }
Пример #5
0
 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}"),
     });
Пример #6
0
        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);
        }
Пример #7
0
 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);
 }
Пример #8
0
        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));
        }
Пример #9
0
        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;
             */
        }
Пример #10
0
        internal static string GetCallingConvention(SignatureCallingConvention callingConvention)
        {
            if (callingConvention == SignatureCallingConvention.Default)
            {
                return("managed");
            }

            if (callingConvention == SignatureCallingConvention.Unmanaged)
            {
                return("unmanaged");
            }

            return($"unmanaged[{callingConvention}]");
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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;
            }
            }
        }
Пример #13
0
        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();
        }
Пример #14
0
        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));
        }
Пример #15
0
        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);
        }
Пример #16
0
        /// <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));
        }
Пример #17
0
        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);
        }
Пример #18
0
        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));
        }
Пример #19
0
 public SignatureHeader(SignatureKind kind, SignatureCallingConvention convention, SignatureAttributes attributes)
     : this((byte)((int)kind | (int)convention | (int)attributes))
 {
 }
Пример #20
0
 // 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));
 }
Пример #21
0
 // 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)));
 }
Пример #22
0
 internal static bool IsValid(this SignatureCallingConvention convention) =>
 convention <= SignatureCallingConvention.VarArgs ||
 convention == SignatureCallingConvention.Unmanaged;
Пример #23
0
        /// <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);
        }
Пример #24
0
        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);
        }