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.BlobBuilder(); 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); }
internal virtual void Free() { if (_lazyRegularInstructions != null) { _lazyRegularInstructions.Free(); _lazyRegularInstructions = null; } }
/// <summary> /// Produces a serialized blob of all constant initializers. /// Non-constant 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.BlobBuilder(initializers.Length * 4); SerializeArrayRecursive(writer, initializers); return(writer.ToImmutableArray()); }
public void Serialize(Cci.BlobBuilder writer) { switch (this.Discriminator) { case ConstantValueTypeDiscriminator.Boolean: writer.WriteBoolean(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.WriteInt16(this.Int16Value); break; case ConstantValueTypeDiscriminator.UInt16: writer.WriteUInt16(this.UInt16Value); break; case ConstantValueTypeDiscriminator.Single: writer.WriteSingle(this.SingleValue); break; case ConstantValueTypeDiscriminator.Int32: writer.WriteInt32(this.Int32Value); break; case ConstantValueTypeDiscriminator.UInt32: writer.WriteUInt32(this.UInt32Value); break; case ConstantValueTypeDiscriminator.Double: writer.WriteDouble(this.DoubleValue); break; case ConstantValueTypeDiscriminator.Int64: writer.WriteInt64(this.Int64Value); break; case ConstantValueTypeDiscriminator.UInt64: writer.WriteUInt64(this.UInt64Value); break; default: throw ExceptionUtilities.UnexpectedValue(this.Discriminator); } }
internal void SerializeLocalSlots(Cci.BlobBuilder 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.WriteCompressedInteger((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.WriteCompressedInteger((uint)(localSlot.Id.SyntaxOffset - syntaxOffsetBaseline)); if (hasOrdinal) { writer.WriteCompressedInteger((uint)localSlot.Id.Ordinal); } } }
private static void WriteOpCode(Cci.BlobBuilder 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)); } }
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.BlobBuilder(); 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); }
private void SerializeArrayRecursive(Cci.BlobBuilder 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); } } } }
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.BlobBuilder(); 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); }
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.BlobBuilder(); 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); }
internal void SerializeLambdaMap(Cci.BlobBuilder writer) { Debug.Assert(this.MethodOrdinal >= -1); writer.WriteCompressedInteger((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.WriteCompressedInteger((uint)(-syntaxOffsetBaseline)); writer.WriteCompressedInteger((uint)this.Closures.Length); foreach (ClosureDebugInfo info in this.Closures) { writer.WriteCompressedInteger((uint)(info.SyntaxOffset - syntaxOffsetBaseline)); } foreach (LambdaDebugInfo info in this.Lambdas) { Debug.Assert(info.ClosureOrdinal >= LambdaDebugInfo.MinClosureOrdinal); Debug.Assert(info.LambdaId.Generation == 0); writer.WriteCompressedInteger((uint)(info.SyntaxOffset - syntaxOffsetBaseline)); writer.WriteCompressedInteger((uint)(info.ClosureOrdinal - LambdaDebugInfo.MinClosureOrdinal)); } }
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.BlobBuilder(); 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); }
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.BlobBuilder(); 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); }
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.BlobBuilder(); 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); }
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.BlobBuilder(); 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); }
/// <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.BlobBuilder(initializers.Length * 4); SerializeArrayRecursive(writer, initializers); return writer.ToImmutableArray(); }