Пример #1
0
        private void WriteAlignedBlobHeap(BlobBuilder builder)
        {
            int alignment = BitArithmetic.Align(_blobHeapSize, 4) - _blobHeapSize;

            var writer = new BlobWriter(builder.ReserveBytes(_blobHeapSize + alignment));

            // Perf consideration: With large heap the following loop may cause a lot of cache misses
            // since the order of entries in _blobs dictionary depends on the hash of the array values,
            // which is not correlated to the heap index. If we observe such issue we should order
            // the entries by heap position before running this loop.

            int startOffset = _blobHeapStartOffset;

            foreach (var entry in _blobs)
            {
                int heapOffset = entry.Value.GetHeapOffset();
                var blob       = entry.Key;

                writer.Offset = (heapOffset == 0) ? 0 : heapOffset - startOffset;
                writer.WriteCompressedInteger(blob.Length);
                writer.WriteBytes(blob);
            }

            writer.Offset = _blobHeapSize;
            writer.WriteBytes(0, alignment);
        }
Пример #2
0
        // TODO:
        // WriteBytes(byte*)
        // WriteBytes(stream)
        // WriteBytes(byte[])
        // WriteBytes(IA<byte>)
        // WriteReference

        private static void TestCompressedUnsignedInteger(byte[] expected, int value)
        {
            var writer = new BlobWriter(4);

            writer.WriteCompressedInteger(value);
            AssertEx.Equal(expected, writer.ToArray());

            var builder = new BlobBuilder();

            builder.WriteCompressedInteger(value);
            AssertEx.Equal(expected, builder.ToArray());
        }
        public void CompressUnsignedIntegersFromSpecExamples()
        {
            // These examples are straight from the CLI spec.

            TestCompressedUnsignedInteger(new byte[] { 0x00 }, 0);
            TestCompressedUnsignedInteger(new byte[] { 0x03 }, 0x03);
            TestCompressedUnsignedInteger(new byte[] { 0x7f }, 0x7F);
            TestCompressedUnsignedInteger(new byte[] { 0x80, 0x80 }, 0x80);
            TestCompressedUnsignedInteger(new byte[] { 0xAE, 0x57 }, 0x2E57);
            TestCompressedUnsignedInteger(new byte[] { 0xBF, 0xFF }, 0x3FFF);
            TestCompressedUnsignedInteger(new byte[] { 0xC0, 0x00, 0x40, 0x00 }, 0x4000);
            TestCompressedUnsignedInteger(new byte[] { 0xDF, 0xFF, 0xFF, 0xFF }, 0x1FFFFFFF);

            var writer  = new BlobWriter(4);
            var builder = new BlobBuilder();

            Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(-1));
            Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(-1));
            Assert.Throws <ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1));
        }
        private void WriteBlobHeap(BlobBuilder builder)
        {
            var writer = new BlobWriter(builder.ReserveBytes(_blobHeapSize));

            // Perf consideration: With large heap the following loop may cause a lot of cache misses
            // since the order of entries in _blobs dictionary depends on the hash of the array values,
            // which is not correlated to the heap index. If we observe such issue we should order
            // the entries by heap position before running this loop.
            foreach (var entry in _blobs)
            {
                int heapOffset = MetadataTokens.GetHeapOffset(entry.Value);
                var blob       = entry.Key;

                writer.Offset = heapOffset;
                writer.WriteCompressedInteger(blob.Length);
                writer.WriteBytes(blob);
            }
        }
        private void WriteBlobHeap(BlobBuilder builder)
        {
            var writer = new BlobWriter(builder.ReserveBytes(_blobHeapSize));

            // Perf consideration: With large heap the following loop may cause a lot of cache misses
            // since the order of entries in _blobs dictionary depends on the hash of the array values,
            // which is not correlated to the heap index. If we observe such issue we should order
            // the entries by heap position before running this loop.
            foreach (var entry in _blobs)
            {
                int heapOffset = MetadataTokens.GetHeapOffset(entry.Value);
                var blob = entry.Key;

                writer.Offset = heapOffset;
                writer.WriteCompressedInteger(blob.Length);
                writer.WriteBytes(blob);
            }
        }
Пример #6
0
        private void InitializeValueAndSignature()
        {
            var mdReader = _symReader.MetadataReader;
            var constant = mdReader.GetLocalConstant(_handle);

            var sigReader = mdReader.GetBlobReader(constant.Signature);
            var sigWriter = new BlobWriter(sigReader.Length);

            // custom modifiers:
            int rawTypeCode;
            while (true)
            {
                rawTypeCode = sigReader.ReadCompressedInteger();
                if (rawTypeCode == (int)SignatureTypeCode.OptionalModifier || rawTypeCode == (int)SignatureTypeCode.RequiredModifier)
                {
                    sigReader.ReadCompressedInteger();
                }
                else 
                {
                    break;
                }
            }

            int customModifiersLength = sigReader.Offset - 1;
            if (customModifiersLength > 0)
            {
                sigWriter.Write(mdReader.GetBlobBytes(constant.Signature), 0, customModifiersLength);
            }

            object translatedValue;
            if (rawTypeCode == (int)MetadataUtilities.SignatureTypeCode_ValueType || 
                rawTypeCode == (int)MetadataUtilities.SignatureTypeCode_Class)
            {
                var typeHandle = sigReader.ReadTypeHandle();
                if (sigReader.RemainingBytes == 0)
                {
                    // null reference is returned as a boxed integer 0:
                    translatedValue = NullReferenceValue;
                }
                else
                {
                    string qualifiedName = _symReader.PdbReader.GetMetadataImport().GetQualifiedTypeName(typeHandle);
                    if (qualifiedName == "System.Decimal")
                    {
                        translatedValue = sigReader.ReadDecimal();
                    }
                    else if (qualifiedName == "System.DateTime")
                    {
                        translatedValue = BitConverter.Int64BitsToDouble(sigReader.ReadDateTime().Ticks);
                    }
                    else 
                    {
                        // unknown (not produced by C# or VB)
                        translatedValue = null;
                    }
                }

                sigWriter.Write((byte)rawTypeCode);
                sigWriter.WriteCompressedInteger(MetadataUtilities.GetTypeDefOrRefOrSpecCodedIndex(typeHandle));
            }
            else
            {
                bool isEnumTypeCode;
                translatedValue = ReadAndTranslateValue(ref sigReader, (SignatureTypeCode)rawTypeCode, out isEnumTypeCode);

                if (sigReader.RemainingBytes == 0)
                {
                    // primitive type code:
                    sigWriter.Write((byte)rawTypeCode);
                }
                else if (isEnumTypeCode)
                {
                    var enumTypeHandle = sigReader.ReadTypeHandle();

                    // enum type signature:
                    sigWriter.Write((byte)MetadataUtilities.SignatureTypeCode_ValueType);
                    sigWriter.WriteCompressedInteger(MetadataUtilities.GetTypeDefOrRefOrSpecCodedIndex(enumTypeHandle));
                }
                else
                {
                    throw new BadImageFormatException();
                }
            }

            _lazyValue = translatedValue;
            _lazySignature = sigWriter.ToArray();
        }
Пример #7
0
        public void CompressUnsignedIntegersFromSpecExamples()
        {
            // These examples are straight from the CLI spec.

            TestCompressedUnsignedInteger(new byte[] { 0x00 }, 0);
            TestCompressedUnsignedInteger(new byte[] { 0x03 }, 0x03);
            TestCompressedUnsignedInteger(new byte[] { 0x7f }, 0x7F);
            TestCompressedUnsignedInteger(new byte[] { 0x80, 0x80 }, 0x80);
            TestCompressedUnsignedInteger(new byte[] { 0xAE, 0x57 }, 0x2E57);
            TestCompressedUnsignedInteger(new byte[] { 0xBF, 0xFF }, 0x3FFF);
            TestCompressedUnsignedInteger(new byte[] { 0xC0, 0x00, 0x40, 0x00 }, 0x4000);
            TestCompressedUnsignedInteger(new byte[] { 0xDF, 0xFF, 0xFF, 0xFF }, 0x1FFFFFFF);

            var writer = new BlobWriter(4);
            var builder = new BlobBuilder();

            Assert.Throws<ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => writer.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(-1));
            Assert.Throws<ArgumentOutOfRangeException>(() => builder.WriteCompressedInteger(BlobWriterImpl.MaxCompressedIntegerValue + 1));
        }
Пример #8
0
        // TODO: 
        // WriteBytes(byte*)
        // WriteBytes(stream)
        // WriteBytes(byte[])
        // WriteBytes(IA<byte>)
        // WriteReference

        private static void TestCompressedUnsignedInteger(byte[] expected, int value)
        {
            var writer = new BlobWriter(4);
            writer.WriteCompressedInteger(value);
            AssertEx.Equal(expected, writer.ToArray());

            var builder = new BlobBuilder();
            builder.WriteCompressedInteger(value);
            AssertEx.Equal(expected, builder.ToArray());
        }