예제 #1
0
        public void EditAndContinueLambdaAndClosureMap_NegativeSyntaxOffsets()
        {
            var slots = ImmutableArray <LocalSlotDebugInfo> .Empty;

            var closures = ImmutableArray.Create(
                new ClosureDebugInfo(-100, new DebugId(0, 0)),
                new ClosureDebugInfo(10, new DebugId(1, 0)),
                new ClosureDebugInfo(-200, new DebugId(2, 0)));

            var lambdas = ImmutableArray.Create(
                new LambdaDebugInfo(20, new DebugId(0, 0), 1),
                new LambdaDebugInfo(-50, new DebugId(1, 0), 0),
                new LambdaDebugInfo(-180, new DebugId(2, 0), LambdaDebugInfo.StaticClosureOrdinal));

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(0x7b, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x7C, 0x80, 0xC8, 0x03, 0x64, 0x80, 0xD2, 0x00, 0x80, 0xDC, 0x03, 0x80, 0x96, 0x02, 0x14, 0x01 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }
예제 #2
0
 internal virtual void Free()
 {
     if (_lazyRegularInstructions != null)
     {
         _lazyRegularInstructions.Free();
         _lazyRegularInstructions = null;
     }
 }
예제 #3
0
        /// <summary>
        /// Produces a serialized blob of all constant initializers.
        /// Nonconstant initializers are matched with a zero of corresponding size.
        /// </summary>
        private ImmutableArray <byte> GetRawData(ImmutableArray <BoundExpression> initializers)
        {
            // the initial size is a guess.
            // there is no point to be precise here as MemoryStream always has N + 1 storage
            // and will need to be trimmed regardless
            var writer = new Cci.BlobWriter((uint)(initializers.Length * 4));

            SerializeArrayRecursive(writer, initializers);

            return(writer.ToImmutableArray());
        }
예제 #4
0
        public void Serialize(Cci.BlobWriter writer)
        {
            switch (this.Discriminator)
            {
            case ConstantValueTypeDiscriminator.Boolean:
                writer.WriteBool(this.BooleanValue);
                break;

            case ConstantValueTypeDiscriminator.SByte:
                writer.WriteSbyte(this.SByteValue);
                break;

            case ConstantValueTypeDiscriminator.Byte:
                writer.WriteByte(this.ByteValue);
                break;

            case ConstantValueTypeDiscriminator.Char:
            case ConstantValueTypeDiscriminator.Int16:
                writer.WriteShort(this.Int16Value);
                break;

            case ConstantValueTypeDiscriminator.UInt16:
                writer.WriteUshort(this.UInt16Value);
                break;

            case ConstantValueTypeDiscriminator.Single:
                writer.WriteFloat(this.SingleValue);
                break;

            case ConstantValueTypeDiscriminator.Int32:
                writer.WriteInt(this.Int32Value);
                break;

            case ConstantValueTypeDiscriminator.UInt32:
                writer.WriteUint(this.UInt32Value);
                break;

            case ConstantValueTypeDiscriminator.Double:
                writer.WriteDouble(this.DoubleValue);
                break;

            case ConstantValueTypeDiscriminator.Int64:
                writer.WriteLong(this.Int64Value);
                break;

            case ConstantValueTypeDiscriminator.UInt64:
                writer.WriteUlong(this.UInt64Value);
                break;

            default: throw ExceptionUtilities.UnexpectedValue(this.Discriminator);
            }
        }
예제 #5
0
        internal void SerializeLocalSlots(Cci.BlobWriter writer)
        {
            int syntaxOffsetBaseline = -1;

            foreach (LocalSlotDebugInfo localSlot in this.LocalSlots)
            {
                if (localSlot.Id.SyntaxOffset < syntaxOffsetBaseline)
                {
                    syntaxOffsetBaseline = localSlot.Id.SyntaxOffset;
                }
            }

            if (syntaxOffsetBaseline != -1)
            {
                writer.WriteByte(SyntaxOffsetBaseline);
                writer.WriteCompressedUInt((uint)(-syntaxOffsetBaseline));
            }

            foreach (LocalSlotDebugInfo localSlot in this.LocalSlots)
            {
                SynthesizedLocalKind kind = localSlot.SynthesizedKind;
                Debug.Assert(kind <= SynthesizedLocalKind.MaxValidValueForLocalVariableSerializedToDebugInformation);

                if (!kind.IsLongLived())
                {
                    writer.WriteByte(0);
                    continue;
                }

                byte b = (byte)(kind + 1);
                Debug.Assert((b & (1 << 7)) == 0);

                bool hasOrdinal = localSlot.Id.Ordinal > 0;

                if (hasOrdinal)
                {
                    b |= 1 << 7;
                }

                writer.WriteByte(b);
                writer.WriteCompressedUInt((uint)(localSlot.Id.SyntaxOffset - syntaxOffsetBaseline));

                if (hasOrdinal)
                {
                    writer.WriteCompressedUInt((uint)localSlot.Id.Ordinal);
                }
            }
        }
예제 #6
0
        private static void WriteOpCode(Cci.BlobWriter writer, ILOpCode code)
        {
            var size = code.Size();

            if (size == 1)
            {
                writer.WriteByte((byte)code);
            }
            else
            {
                // IL opcodes that occupy two bytes are written to
                // the byte stream with the high-order byte first,
                // in contrast to the little-endian format of the
                // numeric arguments and tokens.

                Debug.Assert(size == 2);
                writer.WriteByte((byte)((ushort)code >> 8));
                writer.WriteByte((byte)((ushort)code & 0xff));
            }
        }
예제 #7
0
 private void SerializeArrayRecursive(Cci.BlobWriter bw, ImmutableArray <BoundExpression> inits)
 {
     if (inits.Length != 0)
     {
         if (inits[0].Kind == BoundKind.ArrayInitialization)
         {
             foreach (var init in inits)
             {
                 SerializeArrayRecursive(bw, ((BoundArrayInitialization)init).Initializers);
             }
         }
         else
         {
             foreach (var init in inits)
             {
                 AsConstOrDefault(init).Serialize(bw);
             }
         }
     }
 }
예제 #8
0
        public void EditAndContinueLambdaAndClosureMap_NoClosures()
        {
            var slots = ImmutableArray <LocalSlotDebugInfo> .Empty;

            var closures = ImmutableArray <ClosureDebugInfo> .Empty;
            var lambdas  = ImmutableArray.Create(new LambdaDebugInfo(20, new DebugId(0, 0), LambdaDebugInfo.StaticClosureOrdinal));

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(-1, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x00, 0x01, 0x00, 0x15, 0x01 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }
예제 #9
0
        public void EditAndContinueLambdaAndClosureMap_NoLambdas()
        {
            // should not happen in practice, but EditAndContinueMethodDebugInformation should handle it just fine

            var slots    = ImmutableArray <LocalSlotDebugInfo> .Empty;
            var closures = ImmutableArray <ClosureDebugInfo> .Empty;
            var lambdas  = ImmutableArray <LambdaDebugInfo> .Empty;

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(10, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x0B, 0x01, 0x00 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray <byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }
예제 #10
0
        public void EditAndContinueLocalSlotMap_NegativeSyntaxOffsets()
        {
            var slots = ImmutableArray.Create(
                new LocalSlotDebugInfo(SynthesizedLocalKind.UserDefined, new LocalDebugId(-1, 10)),
                new LocalSlotDebugInfo(SynthesizedLocalKind.TryAwaitPendingCaughtException, new LocalDebugId(-20000, 10)));

            var closures = ImmutableArray <ClosureDebugInfo> .Empty;
            var lambdas  = ImmutableArray <LambdaDebugInfo> .Empty;

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(123, slots, closures, lambdas).SerializeLocalSlots(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0xFF, 0xC0, 0x00, 0x4E, 0x20, 0x81, 0xC0, 0x00, 0x4E, 0x1F, 0x0A, 0x9A, 0x00, 0x0A }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(bytes, default(ImmutableArray <byte>)).LocalSlots;

            AssertEx.Equal(slots, deserialized);
        }
예제 #11
0
        internal void SerializeLambdaMap(Cci.BlobWriter writer)
        {
            Debug.Assert(this.MethodOrdinal >= -1);
            writer.WriteCompressedUInt((uint)(this.MethodOrdinal + 1));

            int syntaxOffsetBaseline = -1;

            foreach (ClosureDebugInfo info in this.Closures)
            {
                if (info.SyntaxOffset < syntaxOffsetBaseline)
                {
                    syntaxOffsetBaseline = info.SyntaxOffset;
                }
            }

            foreach (LambdaDebugInfo info in this.Lambdas)
            {
                if (info.SyntaxOffset < syntaxOffsetBaseline)
                {
                    syntaxOffsetBaseline = info.SyntaxOffset;
                }
            }

            writer.WriteCompressedUInt((uint)(-syntaxOffsetBaseline));
            writer.WriteCompressedUInt((uint)this.Closures.Length);

            foreach (ClosureDebugInfo info in this.Closures)
            {
                writer.WriteCompressedUInt((uint)(info.SyntaxOffset - syntaxOffsetBaseline));
            }

            foreach (LambdaDebugInfo info in this.Lambdas)
            {
                Debug.Assert(info.ClosureOrdinal >= LambdaDebugInfo.MinClosureOrdinal);
                Debug.Assert(info.LambdaId.Generation == 0);

                writer.WriteCompressedUInt((uint)(info.SyntaxOffset - syntaxOffsetBaseline));
                writer.WriteCompressedUInt((uint)(info.ClosureOrdinal - LambdaDebugInfo.MinClosureOrdinal));
            }
        }
예제 #12
0
 internal virtual void Free()
 {
     if (_lazyRegularInstructions != null)
     {
         _lazyRegularInstructions.Free();
         _lazyRegularInstructions = null;
     }
 }
예제 #13
0
        public void EditAndContinueLambdaAndClosureMap_NoLambdas()
        {
            // should not happen in practice, but EditAndContinueMethodDebugInformation should handle it just fine

            var slots = ImmutableArray<LocalSlotDebugInfo>.Empty;
            var closures = ImmutableArray<ClosureDebugInfo>.Empty;
            var lambdas = ImmutableArray<LambdaDebugInfo>.Empty;

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(10, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x0B, 0x01, 0x00 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray<byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }
예제 #14
0
        public void EditAndContinueLambdaAndClosureMap_NegativeSyntaxOffsets()
        {
            var slots = ImmutableArray<LocalSlotDebugInfo>.Empty;

            var closures = ImmutableArray.Create(
                new ClosureDebugInfo(-100, new DebugId(0, 0)),
                new ClosureDebugInfo(10, new DebugId(1, 0)),
                new ClosureDebugInfo(-200, new DebugId(2, 0)));

            var lambdas = ImmutableArray.Create(
                new LambdaDebugInfo(20, new DebugId(0, 0), 1),
                new LambdaDebugInfo(-50, new DebugId(1, 0), 0),
                new LambdaDebugInfo(-180, new DebugId(2, 0), LambdaDebugInfo.StaticClosureOrdinal));

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(0x7b, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x7C, 0x80, 0xC8, 0x03, 0x64, 0x80, 0xD2, 0x00, 0x80, 0xDC, 0x03, 0x80, 0x96, 0x02, 0x14, 0x01 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray<byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }
예제 #15
0
        public void EditAndContinueLocalSlotMap_NegativeSyntaxOffsets()
        {
            var slots = ImmutableArray.Create(
                new LocalSlotDebugInfo(SynthesizedLocalKind.UserDefined, new LocalDebugId(-1, 10)),
                new LocalSlotDebugInfo(SynthesizedLocalKind.TryAwaitPendingCaughtException, new LocalDebugId(-20000, 10)));

            var closures = ImmutableArray<ClosureDebugInfo>.Empty;
            var lambdas = ImmutableArray<LambdaDebugInfo>.Empty;

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(123, slots, closures, lambdas).SerializeLocalSlots(cmw);

            var bytes = cmw.ToImmutableArray();
            AssertEx.Equal(new byte[] { 0xFF, 0xC0, 0x00, 0x4E, 0x20, 0x81, 0xC0, 0x00, 0x4E, 0x1F, 0x0A, 0x9A, 0x00, 0x0A }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(bytes, default(ImmutableArray<byte>)).LocalSlots;

            AssertEx.Equal(slots, deserialized);
        }
예제 #16
0
        /// <summary>
        /// Produces a serialized blob of all constant initializers.
        /// Nonconstant initializers are matched with a zero of corresponding size.
        /// </summary>
        private ImmutableArray<byte> GetRawData(ImmutableArray<BoundExpression> initializers)
        {
            // the initial size is a guess.
            // there is no point to be precise here as MemoryStream always has N + 1 storage 
            // and will need to be trimmed regardless
            var writer = new Cci.BlobWriter(initializers.Length * 4);

            SerializeArrayRecursive(writer, initializers);

            return writer.ToImmutableArray();
        }
예제 #17
0
        public void EditAndContinueLambdaAndClosureMap_NoClosures()
        {
            var slots = ImmutableArray<LocalSlotDebugInfo>.Empty;

            var closures = ImmutableArray<ClosureDebugInfo>.Empty;
            var lambdas = ImmutableArray.Create(new LambdaDebugInfo(20, new DebugId(0, 0), LambdaDebugInfo.StaticClosureOrdinal));

            var cmw = new Cci.BlobWriter();

            new EditAndContinueMethodDebugInformation(-1, slots, closures, lambdas).SerializeLambdaMap(cmw);

            var bytes = cmw.ToImmutableArray();

            AssertEx.Equal(new byte[] { 0x00, 0x01, 0x00, 0x15, 0x01 }, bytes);

            var deserialized = EditAndContinueMethodDebugInformation.Create(default(ImmutableArray<byte>), bytes);

            AssertEx.Equal(closures, deserialized.Closures);
            AssertEx.Equal(lambdas, deserialized.Lambdas);
        }