コード例 #1
0
        public void SignatureTypeEncoder_FunctionPointer()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);

            Assert.Same(b, e.Builder);

            var m = e.FunctionPointer(
                SignatureCallingConvention.CDecl,
                FunctionPointerAttributes.HasThis,
                genericParameterCount: 1);

            Assert.Same(b, m.Builder);

            AssertEx.Equal(new byte[] { 0x1B, 0x21, 0x01 }, b.ToArray());
            b.Clear();

            e.FunctionPointer(
                SignatureCallingConvention.Default,
                FunctionPointerAttributes.HasExplicitThis,
                genericParameterCount: 0);

            AssertEx.Equal(new byte[] { 0x1B, 0x60 }, b.ToArray());
            b.Clear();

            e.FunctionPointer();

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

            AssertExtensions.Throws <ArgumentException>("attributes", () => e.FunctionPointer(0, (FunctionPointerAttributes)1000, genericParameterCount: 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: ushort.MaxValue + 1));
            Assert.Equal(0, b.Count);
        }
コード例 #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.");
            }
        }
コード例 #3
0
        public void SignatureTypeEncoder_FunctionPointer()
        {
            var b = new BlobBuilder();
            var e = new SignatureTypeEncoder(b);
            Assert.Same(b, e.Builder);

            var m = e.FunctionPointer(
                SignatureCallingConvention.CDecl,
                FunctionPointerAttributes.HasThis,
                genericParameterCount: 1);

            Assert.Same(b, m.Builder);

            AssertEx.Equal(new byte[] { 0x1B, 0x21, 0x01 }, b.ToArray());
            b.Clear();

            e.FunctionPointer(
                SignatureCallingConvention.Default,
                FunctionPointerAttributes.HasExplicitThis,
                genericParameterCount: 0);

            AssertEx.Equal(new byte[] { 0x1B, 0x60 }, b.ToArray());
            b.Clear();

            e.FunctionPointer();

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

            Assert.Throws<ArgumentException>(() => e.FunctionPointer(0, (FunctionPointerAttributes)1000, genericParameterCount: 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: -1));
            Assert.Throws<ArgumentOutOfRangeException>(() => e.FunctionPointer(0, 0, genericParameterCount: ushort.MaxValue + 1));
            Assert.Equal(0, b.Count);
        }