상속: TypeSpecificationSignature
예제 #1
0
        public void CreateArrayField()
        {
            // set up temp assembly.
            var assembly = Utilities.CreateTempNetAssembly();
            var typeSystem = assembly.NetDirectory.MetadataHeader.TypeSystem;
            var tableStream = assembly.NetDirectory.MetadataHeader.GetStream<TableStream>();
            var fieldTable = tableStream.GetTable<FieldDefinition>();
            var importer = new ReferenceImporter(tableStream);

            // create field.
            var arraySignature = new ArrayTypeSignature(typeSystem.Int32);
            arraySignature.Dimensions.Add(new ArrayDimension(2, 1));
            arraySignature.Dimensions.Add(new ArrayDimension(2));
            arraySignature.Dimensions.Add(new ArrayDimension());

            var field = new FieldDefinition(FieldName, FieldAttributes.Public | FieldAttributes.Static,
                new FieldSignature(importer.ImportTypeSignature(arraySignature)));
            fieldTable.Add(field);

            // build and validate.
            assembly = Utilities.RebuildNetAssembly(assembly);
            fieldTable = assembly.NetDirectory.MetadataHeader.GetStream<TableStream>().GetTable<FieldDefinition>();
            field = fieldTable.First(x => x.Name == FieldName);

            Assert.IsInstanceOfType(field.Signature.FieldType, typeof(ArrayTypeSignature));
            Utilities.ValidateType(arraySignature, field.Signature.FieldType);
        }
예제 #2
0
        private static TypeSignature ReadTypeSignature(
            MetadataImage image,
            IBinaryStreamReader reader,
            RecursionProtection protection)
        {
            var elementType = (ElementType)reader.ReadByte();

            switch (elementType)
            {
            case ElementType.Array:
                return(ArrayTypeSignature.FromReader(image, reader, protection));

            case ElementType.Boxed:
                return(BoxedTypeSignature.FromReader(image, reader, protection));

            case ElementType.ByRef:
                return(ByReferenceTypeSignature.FromReader(image, reader, protection));

            case ElementType.CModOpt:
                return(OptionalModifierSignature.FromReader(image, reader, protection));

            case ElementType.CModReqD:
                return(RequiredModifierSignature.FromReader(image, reader, protection));

            case ElementType.Class:
                return(TypeDefOrRefSignature.FromReader(image, reader, protection));

            case ElementType.FnPtr:
                return(FunctionPointerTypeSignature.FromReader(image, reader, protection));

            case ElementType.GenericInst:
                return(GenericInstanceTypeSignature.FromReader(image, reader, protection));

            case ElementType.MVar:
                return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Method));

            case ElementType.Pinned:
                return(PinnedTypeSignature.FromReader(image, reader, protection));

            case ElementType.Ptr:
                return(PointerTypeSignature.FromReader(image, reader, protection));

            case ElementType.Sentinel:
                return(SentinelTypeSignature.FromReader(image, reader, protection));

            case ElementType.SzArray:
                return(SzArrayTypeSignature.FromReader(image, reader, protection));

            case ElementType.ValueType:
                var type = TypeDefOrRefSignature.FromReader(image, reader, protection);
                type.IsValueType = true;
                return(type);

            case ElementType.Var:
                return(GenericParameterSignature.FromReader(image, reader, GenericParameterType.Type));

            default:
                return(MsCorLibTypeSignature.FromElementType(image, elementType));
            }
        }
예제 #3
0
        public static TypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            var elementType = (ElementType)reader.ReadByte();

            switch (elementType)
            {
            case ElementType.Array:
                return(ArrayTypeSignature.FromReader(header, reader));

            case ElementType.Boxed:
                return(BoxedTypeSignature.FromReader(header, reader));

            case ElementType.ByRef:
                return(ByReferenceTypeSignature.FromReader(header, reader));

            case ElementType.CModOpt:
                return(OptionalModifierSignature.FromReader(header, reader));

            case ElementType.CModReqD:
                return(RequiredModifierSignature.FromReader(header, reader));

            case ElementType.Class:
                return(TypeDefOrRefSignature.FromReader(header, reader));

            case ElementType.FnPtr:
                return(FunctionPointerTypeSignature.FromReader(header, reader));

            case ElementType.GenericInst:
                return(GenericInstanceTypeSignature.FromReader(header, reader));

            case ElementType.MVar:
                return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Method));

            case ElementType.Pinned:
                return(PinnedTypeSignature.FromReader(header, reader));

            case ElementType.Ptr:
                return(PointerTypeSignature.FromReader(header, reader));

            case ElementType.Sentinel:
                return(SentinelTypeSignature.FromReader(header, reader));

            case ElementType.SzArray:
                return(SzArrayTypeSignature.FromReader(header, reader));

            case ElementType.ValueType:
                var type = TypeDefOrRefSignature.FromReader(header, reader);
                type.IsValueType = true;
                return(type);

            case ElementType.Var:
                return(GenericParameterSignature.FromReader(header, reader, GenericParameterType.Type));

            default:
                return(MsCorLibTypeSignature.FromElementType(header, elementType));
            }
            throw new NotSupportedException();
        }
예제 #4
0
        public override TypeSignature InstantiateGenericTypes(IGenericContext context)
        {
            var arrayType = new ArrayTypeSignature(BaseType.InstantiateGenericTypes(context));

            foreach (var dimension in Dimensions)
            {
                arrayType.Dimensions.Add(new ArrayDimension(dimension.Size, dimension.LowerBound));
            }
            return(arrayType);
        }
예제 #5
0
        public void MatchArrayTypeSignatures()
        {
            var arrayType1 = new ArrayTypeSignature(CreateTypeSig1());
            arrayType1.Dimensions.Add(new ArrayDimension(null, 0));
            arrayType1.Dimensions.Add(new ArrayDimension(null, 0));

            var arrayType2 = new ArrayTypeSignature(CreateTypeSig1());
            arrayType2.Dimensions.Add(new ArrayDimension(null, 0));
            arrayType2.Dimensions.Add(new ArrayDimension(null, 0));

            var arrayType3 = new ArrayTypeSignature(CreateTypeSig1());
            arrayType3.Dimensions.Add(new ArrayDimension(null, 0));
            arrayType3.Dimensions.Add(new ArrayDimension(null, 1));

            VerifyMatching(arrayType1, arrayType2, arrayType3);
        }
예제 #6
0
        public static new ArrayTypeSignature FromReader(MetadataHeader header, IBinaryStreamReader reader)
        {
            long position = reader.Position;
            var signature = new ArrayTypeSignature(TypeSignature.FromReader(header, reader))
            {
                StartOffset = position
            };

            uint rank;
            if (!reader.TryReadCompressedUInt32(out rank))
                return signature;

            uint numSizes;
            if (!reader.TryReadCompressedUInt32(out numSizes))
                return signature;

            var sizes = new uint[numSizes];
            for (int i = 0; i < numSizes; i++)
            {
                if (!reader.TryReadCompressedUInt32(out sizes[i]))
                    return signature;
            }

            uint numLoBounds;
            if (!reader.TryReadCompressedUInt32(out numLoBounds))
                return signature;

            var loBounds = new uint[numLoBounds];
            for (int i = 0; i < numLoBounds; i++)
            {
                if (!reader.TryReadCompressedUInt32(out loBounds[i]))
                    return signature;
            }

            for (int i = 0; i < rank; i++)
            {
                var dimension = new ArrayDimension();
                if (i < numSizes)
                    dimension.Size = (int)sizes[i];
                if (i < numLoBounds)
                    dimension.LowerBound = (int)loBounds[i];
                signature.Dimensions.Add(dimension);
            }

            return signature;
        }
예제 #7
0
        /// <summary>
        /// Reads a single array type signature at the current position of the provided stream reader.
        /// </summary>
        /// <param name="image">The image the array was defined in.</param>
        /// <param name="reader">The reader to use.</param>
        /// <param name="protection">The recursion protection that is used to detect malicious loops in the metadata.</param>
        /// <returns>The read array.</returns>
        public static ArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader, RecursionProtection protection)
        {
            var signature = new ArrayTypeSignature(TypeSignature.FromReader(image, reader, false, protection));

            // Rank
            if (!reader.TryReadCompressedUInt32(out uint rank))
            {
                return(signature);
            }

            // Sizes.
            if (!reader.TryReadCompressedUInt32(out uint numSizes))
            {
                return(signature);
            }

            var sizes = new List <uint>();

            for (int i = 0; i < numSizes; i++)
            {
                if (!reader.TryReadCompressedUInt32(out uint size))
                {
                    return(signature);
                }
                sizes.Add(size);
            }

            // Lower bounds.
            if (!reader.TryReadCompressedUInt32(out uint numLoBounds))
            {
                return(signature);
            }

            var loBounds = new List <uint>();

            for (int i = 0; i < numLoBounds; i++)
            {
                if (!reader.TryReadCompressedUInt32(out uint bound))
                {
                    return(signature);
                }
                loBounds.Add(bound);
            }

            // Create dimensions.
            for (int i = 0; i < rank; i++)
            {
                var dimension = new ArrayDimension();
                if (i < numSizes)
                {
                    dimension.Size = (int)sizes[i];
                }
                if (i < numLoBounds)
                {
                    dimension.LowerBound = (int)loBounds[i];
                }
                signature.Dimensions.Add(dimension);
            }

            return(signature);
        }
예제 #8
0
        public new static ArrayTypeSignature FromReader(MetadataImage image, IBinaryStreamReader reader)
        {
            long position  = reader.Position;
            var  signature = new ArrayTypeSignature(TypeSignature.FromReader(image, reader));

            uint rank;

            if (!reader.TryReadCompressedUInt32(out rank))
            {
                return(signature);
            }

            uint numSizes;

            if (!reader.TryReadCompressedUInt32(out numSizes))
            {
                return(signature);
            }

            var sizes = new uint[numSizes];

            for (int i = 0; i < numSizes; i++)
            {
                if (!reader.TryReadCompressedUInt32(out sizes[i]))
                {
                    return(signature);
                }
            }

            uint numLoBounds;

            if (!reader.TryReadCompressedUInt32(out numLoBounds))
            {
                return(signature);
            }

            var loBounds = new uint[numLoBounds];

            for (int i = 0; i < numLoBounds; i++)
            {
                if (!reader.TryReadCompressedUInt32(out loBounds[i]))
                {
                    return(signature);
                }
            }

            for (int i = 0; i < rank; i++)
            {
                var dimension = new ArrayDimension();
                if (i < numSizes)
                {
                    dimension.Size = (int)sizes[i];
                }
                if (i < numLoBounds)
                {
                    dimension.LowerBound = (int)loBounds[i];
                }
                signature.Dimensions.Add(dimension);
            }

            return(signature);
        }
예제 #9
0
        private ArrayTypeSignature ImportArrayTypeSignature(ArrayTypeSignature signature)
        {
            var newSignature = new ArrayTypeSignature(ImportTypeSignature(signature.BaseType))
            {
                IsValueType = signature.IsValueType
            };

            foreach (var dimension in signature.Dimensions)
            {
                var newDimension = new ArrayDimension();
                if (dimension.Size.HasValue)
                    newDimension.Size = dimension.Size.Value;
                if (dimension.LowerBound.HasValue)
                    newDimension.LowerBound = dimension.LowerBound.Value;
                newSignature.Dimensions.Add(newDimension);
            }
            return newSignature;
        }
예제 #10
0
 private ArrayTypeSignature ImportArrayTypeSignature(Type arrayType)
 {
     var newSignature = new ArrayTypeSignature(ImportTypeSignature(arrayType.GetElementType()))
     {
         IsValueType = arrayType.IsValueType
     };
     for (int i = 0; i < arrayType.GetArrayRank(); i++)
         newSignature.Dimensions.Add(new ArrayDimension());
     return newSignature;
 }
예제 #11
0
        /// <summary>
        /// Determines whether two types are considered equal according to their signature.
        /// </summary>
        /// <param name="signature1">The first type to compare.</param>
        /// <param name="signature2">The second type to compare.</param>
        /// <returns><c>True</c> if the types are considered equal, <c>False</c> otherwise.</returns>
        public bool MatchTypes(ArrayTypeSignature signature1, ArrayTypeSignature signature2)
        {
            if (signature1 == null && signature2 == null)
                return true;
            if (signature1 == null || signature2 == null)
                return false;

            return MatchTypes(signature1.BaseType, signature2.BaseType)
                && signature1.Dimensions.Count == signature2.Dimensions.Count
                && signature1.Dimensions.Where((d, i) => MatchArrayDimensions(d, signature2.Dimensions[i])).Count() == signature1.Dimensions.Count;
        }