Exemplo n.º 1
0
        public void SignatureTypeEncoder_GenericMethodTypeParameter()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);

            e.GenericMethodTypeParameter(0);
            AssertEx.Equal(new byte[] { 0x1E, 0x00 }, b.ToArray());
            b.Clear();

            e.GenericMethodTypeParameter(ushort.MaxValue);
            AssertEx.Equal(new byte[] { 0x1E, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray());
            b.Clear();

            Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericMethodTypeParameter(-1));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.GenericMethodTypeParameter(ushort.MaxValue + 1));
            Assert.Equal(0, b.Count);
        }
Exemplo n.º 2
0
        private void EncodeTypeSignature(SignatureTypeEncoder encoder, TypeDesc type)
        {
            if (type is RuntimeDeterminedType)
            {
                EncodeTypeSignature(encoder, ((RuntimeDeterminedType)type).RuntimeDeterminedDetailsType);
                return;
            }

            switch (type.Category)
            {
            case TypeFlags.Boolean:
                encoder.Boolean(); break;

            case TypeFlags.Byte:
                encoder.Byte(); break;

            case TypeFlags.SByte:
                encoder.SByte(); break;

            case TypeFlags.Char:
                encoder.Char(); break;

            case TypeFlags.Int16:
                encoder.Int16(); break;

            case TypeFlags.UInt16:
                encoder.UInt16(); break;

            case TypeFlags.Int32:
                encoder.Int32(); break;

            case TypeFlags.UInt32:
                encoder.UInt32(); break;

            case TypeFlags.Int64:
                encoder.Int64(); break;

            case TypeFlags.UInt64:
                encoder.UInt64(); break;

            case TypeFlags.Single:
                encoder.Single(); break;

            case TypeFlags.Double:
                encoder.Double(); break;

            case TypeFlags.IntPtr:
                encoder.IntPtr(); break;

            case TypeFlags.UIntPtr:
                encoder.UIntPtr(); break;

            case TypeFlags.Void:
                encoder.Builder.WriteByte((byte)PrimitiveTypeCode.Void);
                break;

            case TypeFlags.SignatureTypeVariable:
                encoder.GenericTypeParameter(((SignatureVariable)type).Index);
                break;

            case TypeFlags.SignatureMethodVariable:
                encoder.GenericMethodTypeParameter(((SignatureMethodVariable)type).Index);
                break;

            case TypeFlags.GenericParameter:
            {
                var genericTypeDesc = (GenericParameterDesc)type;
                if (genericTypeDesc.Kind == GenericParameterKind.Type)
                {
                    encoder.GenericTypeParameter(genericTypeDesc.Index);
                }
                else
                {
                    encoder.GenericMethodTypeParameter(genericTypeDesc.Index);
                }
            }
            break;

            case TypeFlags.FunctionPointer:
            {
                FunctionPointerType fptrType = (FunctionPointerType)type;
                encoder.FunctionPointer(
                    SignatureCallingConvention.Default,
                    fptrType.Signature.IsStatic ? default(FunctionPointerAttributes) : FunctionPointerAttributes.HasThis,
                    fptrType.Signature.GenericParameterCount);

                // Return Type Sig
                EncodeTypeSignature(encoder, fptrType.Signature.ReturnType);

                // Parameter Types Sig
                for (int i = 0; i < fptrType.Signature.Length; i++)
                {
                    EncodeTypeSignature(encoder, fptrType.Signature[i]);
                }
            }
            break;

            case TypeFlags.Array:
            {
                // Skip bounds and lobounds (TODO)
                ImmutableArray <int> bounds      = ImmutableArray.Create <int>();
                ImmutableArray <int> lowerBounds = ImmutableArray.Create <int>();
                encoder.Array(
                    elementType => EncodeTypeSignature(elementType, ((ArrayType)type).ElementType),
                    arrayShape => arrayShape.Shape(((ArrayType)type).Rank, bounds, lowerBounds));
            }
            break;

            case TypeFlags.SzArray:
                encoder.SZArray();
                EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
                break;

            case TypeFlags.ByRef:
                encoder.Builder.WriteByte((byte)SignatureTypeCode.ByReference);
                EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
                break;

            case TypeFlags.Pointer:
                encoder.Builder.WriteByte((byte)SignatureTypeCode.Pointer);
                EncodeTypeSignature(encoder, ((ParameterizedType)type).ParameterType);
                break;

            case TypeFlags.Enum:
            case TypeFlags.Class:
            case TypeFlags.ValueType:
            case TypeFlags.Interface:
            case TypeFlags.Nullable:
            {
                if (type == _typeSystemContext.GetWellKnownType(WellKnownType.TypedReference))
                {
                    encoder.Builder.WriteByte((byte)PrimitiveTypeCode.TypedReference);
                }
                else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.Object))
                {
                    encoder.PrimitiveType(PrimitiveTypeCode.Object);
                }
                else if (type == _typeSystemContext.GetWellKnownType(WellKnownType.String))
                {
                    encoder.PrimitiveType(PrimitiveTypeCode.String);
                }
                else if (type.HasInstantiation && !type.IsGenericDefinition)
                {
                    encoder.GenericInstantiation(MakeTypeRefOrSpecHandle(type.GetTypeDefinition()), type.Instantiation.Length, type.IsValueType);

                    for (int i = 0; i < type.Instantiation.Length; i++)
                    {
                        EncodeTypeSignature(encoder, type.Instantiation[i]);
                    }
                }
                else
                {
                    encoder.Type(MakeTypeRefHandle(type), type.IsValueType);
                }
            }
            break;

            default:
                throw new InvalidOperationException("Attempting to encode an invalid type signature.");
            }
        }
Exemplo n.º 3
0
        internal static void FromSystemType(this SignatureTypeEncoder typeEncoder, Type type,
                                            IAssemblyMetadata metadata)
        {
            if (type.IsByRef)
            {
                throw new ArgumentException("ByRef types should be handled by parameter encoder or return type encoder");
            }
            else if (type.IsPointer)
            {
                typeEncoder.Pointer().FromSystemType(type.GetElementType(), metadata);
            }
            else if (type.IsPrimitive)
            {
                typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type));
            }
            else if (type == typeof(string))
            {
                typeEncoder.String();
            }
            else if (type == typeof(object))
            {
                typeEncoder.Object();
            }
            else if (type == typeof(void))
            {
                throw new ArgumentException(
                          "Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder.",
                          nameof(type));
            }
            else if (type.IsArray)
            {
                var elementType = type.GetElementType();

                if (type.GetArrayRank() == 1)
                {
                    typeEncoder.SZArray().FromSystemType(elementType, metadata);
                }
                else
                {
                    typeEncoder.Array(
                        x => x.FromSystemType(elementType, metadata),
                        x => x.Shape(
                            type.GetArrayRank(),
                            ImmutableArray.Create <int>(),
                            ImmutableArray.CreateRange <int>(Enumerable.Repeat(0, type.GetArrayRank())) // better matches metadata from C#
                            ));
                }
            }
            else if (type.IsGenericType)
            {
                var genericTypeDef   = type.GetGenericTypeDefinition();
                var typeHandler      = metadata.GetTypeHandle(genericTypeDef);
                var genericArguments = type.GetGenericArguments();

                var inst = typeEncoder.GenericInstantiation(typeHandler, genericArguments.Length, type.IsValueType);
                foreach (var ga in genericArguments)
                {
                    if (ga.IsGenericParameter)
                    {
                        inst.AddArgument().GenericTypeParameter(ga.GenericParameterPosition);
                    }
                    else
                    {
                        inst.AddArgument().FromSystemType(ga, metadata);
                    }
                }
            }
            else if (type.IsGenericMethodParameter())
            {
                typeEncoder.GenericMethodTypeParameter(type.GenericParameterPosition);
            }
            else if (type.IsGenericParameter)
            {
                typeEncoder.GenericTypeParameter(type.GenericParameterPosition);
            }
            else
            {
                var typeHandler = metadata.GetTypeHandle(type);
                typeEncoder.Type(typeHandler, type.IsValueType);
            }
        }
Exemplo n.º 4
0
        public void SignatureTypeEncoder_GenericMethodTypeParameter()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);
            Assert.Same(b, e.Builder);

            e.GenericMethodTypeParameter(0);
            AssertEx.Equal(new byte[] { 0x1E, 0x00 }, b.ToArray());
            b.Clear();

            e.GenericMethodTypeParameter(ushort.MaxValue);
            AssertEx.Equal(new byte[] { 0x1E, 0xC0, 0x00, 0xFF, 0xFF }, b.ToArray());
            b.Clear();

            Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericMethodTypeParameter(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.GenericMethodTypeParameter(ushort.MaxValue + 1));
            Assert.Equal(0, b.Count);
        }