提交 e8013eda 编写于 作者: T Tomas Matousek

Mark return value synthesized local as long-lived

上级 343786c1
......@@ -116,7 +116,30 @@ private LocalDefinition LazyReturnTemp
if (result == null)
{
Debug.Assert(!_method.ReturnsVoid, "returning something from void method?");
result = AllocateTemp(_method.ReturnType, _boundBody.Syntax);
var bodySyntax = _methodBodySyntaxOpt;
if (_optimizations == OptimizationLevel.Debug && bodySyntax != null)
{
int syntaxOffset = _method.CalculateLocalSyntaxOffset(bodySyntax.SpanStart, bodySyntax.SyntaxTree);
var localSymbol = new SynthesizedLocal(_method, _method.ReturnType, SynthesizedLocalKind.FunctionReturnValue, bodySyntax);
result = _builder.LocalSlotManager.DeclareLocal(
type: _module.Translate(localSymbol.Type, bodySyntax, _diagnostics),
symbol: localSymbol,
name: null,
kind: localSymbol.SynthesizedKind,
id: new LocalDebugId(syntaxOffset, ordinal: 0),
pdbAttributes: localSymbol.SynthesizedKind.PdbAttributes(),
constraints: LocalSlotConstraints.None,
isDynamic: false,
dynamicTransformFlags: ImmutableArray<TypedConstant>.Empty,
isSlotReusable: localSymbol.SynthesizedKind.IsSlotReusable(_optimizations));
}
else
{
result = AllocateTemp(_method.ReturnType, _boundBody.Syntax);
}
_returnTemp = result;
}
return result;
......
......@@ -610,7 +610,19 @@ private void EmitStateMachineScope(BoundStateMachineScope scope)
// debuggable code. This function is a stub for the logic that decides that.
private bool ShouldUseIndirectReturn()
{
return _optimizations == OptimizationLevel.Debug || _builder.InExceptionHandler;
// If the method/lambda body is a block we define a sequence point for the closing brace of the body
// and associate it with the ret instruction. If there is a return statement we need to store the value
// to a long-lived synthesized local since a sequence point requires an empty evaluation stack.
//
// The emitted pattern is:
// <evaluate return statement expression>
// stloc $ReturnValue
// ldloc $ReturnValue // sequence point
// ret
//
// Do not emit this pattern if the method doesn't include user code or doesn't have a block blody.
return _optimizations == OptimizationLevel.Debug && _method.GenerateDebugInfo && _methodBodySyntaxOpt?.IsKind(SyntaxKind.Block) == true ||
_builder.InExceptionHandler;
}
// Compiler generated return mapped to a block is very likely the synthetic return
......@@ -626,11 +638,13 @@ private bool CanHandleReturnLabel(BoundReturnStatement boundReturnStatement)
private void EmitReturnStatement(BoundReturnStatement boundReturnStatement)
{
this.EmitExpression(boundReturnStatement.ExpressionOpt, true);
var expressionOpt = boundReturnStatement.ExpressionOpt;
this.EmitExpression(expressionOpt, used: true);
if (ShouldUseIndirectReturn())
{
if (boundReturnStatement.ExpressionOpt != null)
if (expressionOpt != null)
{
_builder.EmitLocalStore(LazyReturnTemp);
}
......@@ -653,7 +667,7 @@ private void EmitReturnStatement(BoundReturnStatement boundReturnStatement)
{
if (_indirectReturnState == IndirectReturnState.Needed && CanHandleReturnLabel(boundReturnStatement))
{
if (boundReturnStatement.ExpressionOpt != null)
if (expressionOpt != null)
{
_builder.EmitLocalStore(LazyReturnTemp);
}
......@@ -662,7 +676,7 @@ private void EmitReturnStatement(BoundReturnStatement boundReturnStatement)
}
else
{
_builder.EmitRet(boundReturnStatement.ExpressionOpt == null);
_builder.EmitRet(expressionOpt == null);
}
}
}
......@@ -1435,7 +1449,7 @@ private void FreeLocal(LocalSymbol local)
/// <summary>
/// Allocates a temp without identity.
/// </summary>
private LocalDefinition AllocateTemp(TypeSymbol type, CSharpSyntaxNode syntaxNode)
private LocalDefinition AllocateTemp(TypeSymbol type, SyntaxNode syntaxNode)
{
return _builder.LocalSlotManager.AllocateSlot(
_module.Translate(type, syntaxNode, _diagnostics),
......
......@@ -1075,9 +1075,6 @@ internal override bool CallsAreOmitted(SyntaxTree syntaxTree)
return base.CallsAreOmitted(syntaxTree);
}
internal override bool GenerateDebugInfo
{
get { return !IsAsync; }
}
internal override bool GenerateDebugInfo => !IsAsync && !IsIterator;
}
}
......@@ -544,7 +544,8 @@ static void Main()
{
// Code size 37 (0x25)
.maxstack 1
.locals init (I V_0)
.locals init (I V_0,
I V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: brfalse.s IL_000d
......@@ -561,9 +562,9 @@ .locals init (I V_0)
IL_0019: newobj ""A..ctor()""
IL_001e: stloc.0
IL_001f: ldloc.0
IL_0020: stloc.0
IL_0020: stloc.1
IL_0021: br.s IL_0023
IL_0023: ldloc.0
IL_0023: ldloc.1
IL_0024: ret
}");
// Optimized
......@@ -627,7 +628,8 @@ static void Main()
{
// Code size 39 (0x27)
.maxstack 2
.locals init (I V_0)
.locals init (I V_0,
I V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
......@@ -646,9 +648,9 @@ .locals init (I V_0)
IL_001b: newobj ""C..ctor()""
IL_0020: stloc.0
IL_0021: ldloc.0
IL_0022: stloc.0
IL_0022: stloc.1
IL_0023: br.s IL_0025
IL_0025: ldloc.0
IL_0025: ldloc.1
IL_0026: ret
}");
// Optimized
......@@ -716,7 +718,8 @@ static void Main()
{
// Code size 51 (0x33)
.maxstack 2
.locals init (I V_0)
.locals init (I V_0,
I V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
......@@ -741,9 +744,9 @@ .locals init (I V_0)
IL_0027: newobj ""A..ctor()""
IL_002c: stloc.0
IL_002d: ldloc.0
IL_002e: stloc.0
IL_002e: stloc.1
IL_002f: br.s IL_0031
IL_0031: ldloc.0
IL_0031: ldloc.1
IL_0032: ret
}");
// Optimized
......@@ -821,7 +824,8 @@ static void Main()
{
// Code size 52 (0x34)
.maxstack 2
.locals init (I V_0)
.locals init (I V_0,
I V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
......@@ -847,9 +851,9 @@ .locals init (I V_0)
IL_0028: newobj ""A..ctor()""
IL_002d: stloc.0
IL_002e: ldloc.0
IL_002f: stloc.0
IL_002f: stloc.1
IL_0030: br.s IL_0032
IL_0032: ldloc.0
IL_0032: ldloc.1
IL_0033: ret
}");
// Optimized
......@@ -2171,7 +2175,8 @@ static void Main()
{
// Code size 32 (0x20)
.maxstack 2
.locals init (I V_0)
.locals init (I V_0,
I V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.0
......@@ -2188,9 +2193,9 @@ .locals init (I V_0)
IL_0014: newobj ""B..ctor()""
IL_0019: stloc.0
IL_001a: ldloc.0
IL_001b: stloc.0
IL_001b: stloc.1
IL_001c: br.s IL_001e
IL_001e: ldloc.0
IL_001e: ldloc.1
IL_001f: ret
}");
// Optimized
......
......@@ -1204,20 +1204,14 @@ .maxstack 1
dbg.VerifyIL("Program.M", @"
{
// Code size 18 (0x12)
.maxstack 2
.locals init (Program.<M>d__1 V_0,
System.Collections.Generic.IEnumerator<int> V_1)
// Code size 14 (0xe)
.maxstack 3
IL_0000: ldc.i4.0
IL_0001: newobj ""Program.<M>d__1..ctor(int)""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldarg.0
IL_0009: stfld ""System.Collections.Generic.IEnumerable<int> Program.<M>d__1.items""
IL_000e: ldloc.0
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ret
IL_0006: dup
IL_0007: ldarg.0
IL_0008: stfld ""System.Collections.Generic.IEnumerable<int> Program.<M>d__1.items""
IL_000d: ret
}");
}
......
......@@ -1378,7 +1378,8 @@ static void Main()
// Code size 86 (0x56)
.maxstack 2
.locals init (I V_0, //i
I V_1)
I V_1,
I V_2)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
......@@ -1430,9 +1431,9 @@ .maxstack 2
IL_004a: callvirt ""void I.DoNothing()""
IL_004f: nop
IL_0050: ldloc.0
IL_0051: stloc.1
IL_0051: stloc.2
IL_0052: br.s IL_0054
IL_0054: ldloc.1
IL_0054: ldloc.2
IL_0055: ret
}");
// Optimized
......
......@@ -5224,7 +5224,7 @@ static public void F1(C c)
verifier.VerifyIL("C.<>c__DisplayClass0_0.<F1>b__0", @"
{
// Code size 21 (0x15)
// Code size 19 (0x13)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass0_0.c""
......@@ -5234,13 +5234,12 @@ .maxstack 2
IL_000a: br.s IL_0012
IL_000c: call ""void C.M()""
IL_0011: nop
IL_0012: br.s IL_0014
IL_0014: ret
IL_0012: ret
}");
verifier.VerifyIL("C.F2", @"
{
// Code size 15 (0xf)
// Code size 13 (0xd)
.maxstack 1
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0005
......@@ -5248,8 +5247,7 @@ .maxstack 1
IL_0005: ldarg.0
IL_0006: call ""void C.M()""
IL_000b: nop
IL_000c: br.s IL_000e
IL_000e: ret
IL_000c: ret
}");
}
......@@ -5353,7 +5351,7 @@ T M()
verifier.VerifyIL("C<T>.<>c__DisplayClass0_0.<F1>b__0()", @"
{
// Code size 21 (0x15)
// Code size 19 (0x13)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldfld ""C<T> C<T>.<>c__DisplayClass0_0.c""
......@@ -5363,13 +5361,12 @@ .maxstack 2
IL_000a: br.s IL_0012
IL_000c: call ""T C<T>.M()""
IL_0011: pop
IL_0012: br.s IL_0014
IL_0014: ret
IL_0012: ret
}");
verifier.VerifyIL("C<T>.F2", @"
{
// Code size 15 (0xf)
// Code size 13 (0xd)
.maxstack 1
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0005
......@@ -5377,8 +5374,7 @@ .maxstack 1
IL_0005: ldarg.0
IL_0006: call ""T C<T>.M()""
IL_000b: pop
IL_000c: br.s IL_000e
IL_000e: ret
IL_000c: ret
}");
}
......@@ -5482,7 +5478,7 @@ static public void F1(C c)
verifier.VerifyIL("C.<>c__DisplayClass0_0.<F1>b__0", @"
{
// Code size 21 (0x15)
// Code size 19 (0x13)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass0_0.c""
......@@ -5492,13 +5488,12 @@ .maxstack 2
IL_000a: br.s IL_0012
IL_000c: call ""void* C.M()""
IL_0011: pop
IL_0012: br.s IL_0014
IL_0014: ret
IL_0012: ret
}");
verifier.VerifyIL("C.F2", @"
{
// Code size 15 (0xf)
// Code size 13 (0xd)
.maxstack 1
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0005
......@@ -5506,8 +5501,7 @@ .maxstack 1
IL_0005: ldarg.0
IL_0006: call ""void* C.M()""
IL_000b: pop
IL_000c: br.s IL_000e
IL_000e: ret
IL_000c: ret
}");
}
......
......@@ -54,7 +54,6 @@ static object F(object o)
// Type: display class
CheckEncLogDefinitions(reader1,
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.TypeDef, EditAndContinueOperation.Default),
Row(4, TableIndex.TypeDef, EditAndContinueOperation.AddField),
Row(1, TableIndex.Field, EditAndContinueOperation.Default),
......@@ -116,8 +115,7 @@ void F()
// Method updates
CheckEncLogDefinitions(reader1,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default));
}
......@@ -225,8 +223,7 @@ int F(int a)
// Method updates
CheckEncLogDefinitions(reader1,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default));
......@@ -282,8 +279,7 @@ int F(int a)
// Method updates
CheckEncLogDefinitions(reader1,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default));
}
......@@ -357,8 +353,7 @@ class C : D
// Method updates
CheckEncLogDefinitions(reader1,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -422,7 +417,6 @@ partial class C
// Method updates
CheckEncLogDefinitions(reader1,
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default));
......@@ -484,10 +478,7 @@ void F()
// Method updates for lambdas:
CheckEncLogDefinitions(reader1,
Row(9, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(10, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(11, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(12, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(16, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(17, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -569,12 +560,9 @@ void F()
// Method updates for lambdas:
CheckEncLogDefinitions(reader1,
Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(8, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(9, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(10, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(11, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(12, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(13, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -656,7 +644,6 @@ void F()
CheckEncLogDefinitions(reader1,
Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(8, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -741,7 +728,6 @@ public void F()
Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(8, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(9, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(10, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -826,7 +812,6 @@ public void F()
CheckEncLogDefinitions(reader1,
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(5, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -905,7 +890,6 @@ public void F()
CheckEncLogDefinitions(reader1,
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(5, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(6, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
......@@ -994,32 +978,23 @@ static object F()
// updated:
diff1.VerifyIL("C.<>c.<F>b__1_0", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.2
IL_0002: add
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}
");
// added:
diff1.VerifyIL("C.<>c.<F>b__1_1#1", @"
{
// Code size 9 (0x9)
// Code size 5 (0x5)
.maxstack 2
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4.s 20
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
IL_0004: ret
}
");
......@@ -1035,48 +1010,35 @@ .locals init (int V_0)
// updated:
diff2.VerifyIL("C.<>c.<F>b__1_0", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: add
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}
");
// updated:
diff2.VerifyIL("C.<>c.<F>b__1_1#1", @"
{
// Code size 9 (0x9)
// Code size 5 (0x5)
.maxstack 2
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4.s 30
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
IL_0004: ret
}
");
// added:
diff2.VerifyIL("C.<>c.<F>b__1_2#2", @"
{
// Code size 12 (0xc)
// Code size 8 (0x8)
.maxstack 2
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4 0x300
IL_0006: add
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
IL_0007: ret
}
");
......@@ -1091,48 +1053,35 @@ .locals init (int V_0)
// updated:
diff3.VerifyIL("C.<>c.<F>b__1_0", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.4
IL_0002: add
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}
");
// updated:
diff3.VerifyIL("C.<>c.<F>b__1_1#1", @"
{
// Code size 9 (0x9)
// Code size 5 (0x5)
.maxstack 2
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4.s 40
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
IL_0004: ret
}
");
// updated:
diff3.VerifyIL("C.<>c.<F>b__1_2#2", @"
{
// Code size 12 (0xc)
// Code size 8 (0x8)
.maxstack 2
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldc.i4 0x400
IL_0006: add
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
IL_0007: ret
}
");
}
......@@ -1701,8 +1650,7 @@ static object F()
// Note that even if the change is in the inner lambda such a change will usually impact sequence point
// spans in outer lambda and the method body. So although the IL doesn't change we usually need to update the outer methods.
CheckEncLogDefinitions(reader1,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(7, TableIndex.MethodDef, EditAndContinueOperation.Default));
......@@ -1776,61 +1724,41 @@ public C(int x)
diff1.VerifyIL("C.<>c.<.ctor>b__2_0", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.2
IL_0002: sub
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}");
diff1.VerifyIL("C.<>c.<.ctor>b__2_1", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: sub
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}");
diff1.VerifyIL("C.<>c.<.ctor>b__3_0", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.4
IL_0002: sub
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}");
diff1.VerifyIL("C.<>c.<.ctor>b__3_1", @"
{
// Code size 8 (0x8)
// Code size 4 (0x4)
.maxstack 2
.locals init ([int] V_0,
int V_1)
IL_0000: ldarg.1
IL_0001: ldc.i4.1
IL_0002: sub
IL_0003: stloc.1
IL_0004: br.s IL_0006
IL_0006: ldloc.1
IL_0007: ret
IL_0003: ret
}");
}
......
......@@ -462,20 +462,22 @@ class B
CheckNames(readers, reader1.GetFieldDefNames());
CheckNames(readers, reader1.GetPropertyDefNames(), "R");
CheckNames(readers, reader1.GetMethodDefNames(), "get_R");
CheckEncLog(reader1,
Row(2, TableIndex.AssemblyRef, EditAndContinueOperation.Default),
Row(9, TableIndex.TypeRef, EditAndContinueOperation.Default),
Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(1, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.PropertyMap, EditAndContinueOperation.Default),
Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(2, TableIndex.PropertyMap, EditAndContinueOperation.AddProperty),
Row(2, TableIndex.Property, EditAndContinueOperation.Default),
Row(3, TableIndex.MethodSemantics, EditAndContinueOperation.Default));
CheckEncMap(reader1,
Handle(9, TableIndex.TypeRef),
Handle(5, TableIndex.MethodDef),
Handle(2, TableIndex.StandAloneSig),
Handle(1, TableIndex.StandAloneSig),
Handle(2, TableIndex.PropertyMap),
Handle(2, TableIndex.Property),
Handle(3, TableIndex.MethodSemantics),
......@@ -504,7 +506,6 @@ class B
Row(11, TableIndex.TypeRef, EditAndContinueOperation.Default),
Row(12, TableIndex.TypeRef, EditAndContinueOperation.Default),
Row(13, TableIndex.TypeRef, EditAndContinueOperation.Default),
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.TypeDef, EditAndContinueOperation.AddField),
Row(2, TableIndex.Field, EditAndContinueOperation.Default),
Row(2, TableIndex.TypeDef, EditAndContinueOperation.AddMethod),
......@@ -545,7 +546,6 @@ class B
Handle(9, TableIndex.CustomAttribute),
Handle(10, TableIndex.CustomAttribute),
Handle(11, TableIndex.CustomAttribute),
Handle(3, TableIndex.StandAloneSig),
Handle(3, TableIndex.Property),
Handle(4, TableIndex.Property),
Handle(4, TableIndex.MethodSemantics),
......@@ -4801,32 +4801,34 @@ static int M()
diff1.VerifyIL("C.M", @"
{
// Code size 37 (0x25)
// Code size 40 (0x28)
.maxstack 3
.locals init (C V_0, //c
[unchanged] V_1,
[int] V_2,
C V_3,
int V_4)
[int] V_3,
C V_4,
int V_5,
int V_6)
IL_0000: nop
IL_0001: newobj ""C..ctor()""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.3
IL_0009: ldloc.3
IL_000a: callvirt ""int C.P.get""
IL_000f: stloc.s V_4
IL_0011: ldloc.3
IL_0012: ldloc.s V_4
IL_0014: ldc.i4.1
IL_0015: add
IL_0016: callvirt ""void C.P.set""
IL_001b: nop
IL_001c: ldloc.s V_4
IL_001e: stloc.s V_4
IL_0020: br.s IL_0022
IL_0022: ldloc.s V_4
IL_0024: ret
IL_0008: stloc.s V_4
IL_000a: ldloc.s V_4
IL_000c: callvirt ""int C.P.get""
IL_0011: stloc.s V_5
IL_0013: ldloc.s V_4
IL_0015: ldloc.s V_5
IL_0017: ldc.i4.1
IL_0018: add
IL_0019: callvirt ""void C.P.set""
IL_001e: nop
IL_001f: ldloc.s V_5
IL_0021: stloc.s V_6
IL_0023: br.s IL_0025
IL_0025: ldloc.s V_6
IL_0027: ret
}");
}
......
......@@ -2792,10 +2792,9 @@ public IEnumerable<int> F()
v0.VerifyIL("C.<F>d__0.System.Collections.IEnumerator.MoveNext", @"
{
// Code size 137 (0x89)
// Code size 131 (0x83)
.maxstack 2
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__0.<>1__state""
IL_0006: stloc.0
......@@ -2806,65 +2805,61 @@ .maxstack 2
IL_000d: ldc.i4.1
IL_000e: beq.s IL_0014
IL_0010: br.s IL_0016
IL_0012: br.s IL_001a
IL_0014: br.s IL_007e
IL_0012: br.s IL_0018
IL_0014: br.s IL_007a
IL_0016: ldc.i4.0
IL_0017: stloc.1
IL_0018: ldloc.1
IL_0019: ret
IL_001a: ldarg.0
IL_001b: ldc.i4.m1
IL_001c: stfld ""int C.<F>d__0.<>1__state""
IL_0021: nop
IL_0022: ldarg.0
IL_0023: ldarg.0
IL_0024: ldfld ""C C.<F>d__0.<>4__this""
IL_0029: callvirt ""System.Collections.Generic.IEnumerable<int> C.F()""
IL_002e: stfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_0033: ldarg.0
IL_0034: ldc.i4.0
IL_0035: stfld ""bool C.<F>d__0.<>s__2""
IL_0017: ret
IL_0018: ldarg.0
IL_0019: ldc.i4.m1
IL_001a: stfld ""int C.<F>d__0.<>1__state""
IL_001f: nop
IL_0020: ldarg.0
IL_0021: ldarg.0
IL_0022: ldfld ""C C.<F>d__0.<>4__this""
IL_0027: callvirt ""System.Collections.Generic.IEnumerable<int> C.F()""
IL_002c: stfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_0031: ldarg.0
IL_0032: ldc.i4.0
IL_0033: stfld ""bool C.<F>d__0.<>s__2""
.try
{
IL_003a: ldarg.0
IL_003b: ldfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_0040: ldarg.0
IL_0041: ldflda ""bool C.<F>d__0.<>s__2""
IL_0046: call ""void System.Threading.Monitor.Enter(object, ref bool)""
IL_0038: ldarg.0
IL_0039: ldfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_003e: ldarg.0
IL_003f: ldflda ""bool C.<F>d__0.<>s__2""
IL_0044: call ""void System.Threading.Monitor.Enter(object, ref bool)""
IL_0049: nop
IL_004a: nop
IL_004b: nop
IL_004c: nop
IL_004d: nop
IL_004e: leave.s IL_0065
IL_004c: leave.s IL_0063
}
finally
{
IL_0050: ldarg.0
IL_0051: ldfld ""bool C.<F>d__0.<>s__2""
IL_0056: brfalse.s IL_0064
IL_0058: ldarg.0
IL_0059: ldfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_005e: call ""void System.Threading.Monitor.Exit(object)""
IL_0063: nop
IL_0064: endfinally
IL_004e: ldarg.0
IL_004f: ldfld ""bool C.<F>d__0.<>s__2""
IL_0054: brfalse.s IL_0062
IL_0056: ldarg.0
IL_0057: ldfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_005c: call ""void System.Threading.Monitor.Exit(object)""
IL_0061: nop
IL_0062: endfinally
}
IL_0065: ldarg.0
IL_0066: ldnull
IL_0067: stfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_006c: ldarg.0
IL_006d: ldc.i4.1
IL_006e: stfld ""int C.<F>d__0.<>2__current""
IL_0073: ldarg.0
IL_0074: ldc.i4.1
IL_0075: stfld ""int C.<F>d__0.<>1__state""
IL_007a: ldc.i4.1
IL_007b: stloc.1
IL_007c: br.s IL_0018
IL_007e: ldarg.0
IL_007f: ldc.i4.m1
IL_0080: stfld ""int C.<F>d__0.<>1__state""
IL_0085: ldc.i4.0
IL_0086: stloc.1
IL_0087: br.s IL_0018
IL_0063: ldarg.0
IL_0064: ldnull
IL_0065: stfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_006a: ldarg.0
IL_006b: ldc.i4.1
IL_006c: stfld ""int C.<F>d__0.<>2__current""
IL_0071: ldarg.0
IL_0072: ldc.i4.1
IL_0073: stfld ""int C.<F>d__0.<>1__state""
IL_0078: ldc.i4.1
IL_0079: ret
IL_007a: ldarg.0
IL_007b: ldc.i4.m1
IL_007c: stfld ""int C.<F>d__0.<>1__state""
IL_0081: ldc.i4.0
IL_0082: ret
}");
#if TODO
......
......@@ -1864,7 +1864,8 @@ public ITest28 Test()
{
// Code size 41 (0x29)
.maxstack 2
.locals init (ITest28 V_0)
.locals init (ITest28 V_0,
ITest28 V_1)
IL_0000: nop
IL_0001: ldstr ""00000000-0000-0000-0000-000000000000""
IL_0006: newobj ""System.Guid..ctor(string)""
......@@ -1877,9 +1878,9 @@ .locals init (ITest28 V_0)
IL_001d: callvirt ""void ITest28.P1.set""
IL_0022: nop
IL_0023: ldloc.0
IL_0024: stloc.0
IL_0024: stloc.1
IL_0025: br.s IL_0027
IL_0027: ldloc.0
IL_0027: ldloc.1
IL_0028: ret
}
";
......
......@@ -414,6 +414,9 @@ private Task<int> GetNextInt(Random random)
<method containingType=""ConsoleApplication1.Program"" name=""GetNextInt"" parameterNames=""random"">
<customDebugInfo>
<forward declaringType=""ConsoleApplication1.Program"" methodName=""Main"" parameterNames=""args"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""30"" startColumn=""9"" endLine=""30"" endColumn=""10"" document=""0"" />
......@@ -576,6 +579,139 @@ static async void Await(dynamic d)
</symbols>");
}
[Fact]
public void TestAsyncDebug4()
{
var text = @"
using System;
using System.Threading.Tasks;
class C
{
static async Task<int> F()
{
await Task.Delay(1);
return 1;
}
}";
var v = CompileAndVerify(CreateCompilationWithMscorlib45(text, options: TestOptions.DebugDll));
v.VerifyIL("C.F", @"
{
// Code size 52 (0x34)
.maxstack 2
.locals init (C.<F>d__0 V_0,
System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> V_1)
IL_0000: newobj ""C.<F>d__0..ctor()""
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.Create()""
IL_000c: stfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_0011: ldloc.0
IL_0012: ldc.i4.m1
IL_0013: stfld ""int C.<F>d__0.<>1__state""
IL_0018: ldloc.0
IL_0019: ldfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloca.s V_0
IL_0023: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.Start<C.<F>d__0>(ref C.<F>d__0)""
IL_0028: ldloc.0
IL_0029: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_002e: call ""System.Threading.Tasks.Task<int> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.Task.get""
IL_0033: ret
}",
sequencePoints: "C.F");
v.VerifyIL("C.<F>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @"
{
// Code size 168 (0xa8)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter V_2,
C.<F>d__0 V_3,
System.Exception V_4)
~IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__0.<>1__state""
IL_0006: stloc.0
.try
{
~IL_0007: ldloc.0
IL_0008: brfalse.s IL_000c
IL_000a: br.s IL_000e
IL_000c: br.s IL_0048
-IL_000e: nop
-IL_000f: ldc.i4.1
IL_0010: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.Delay(int)""
IL_0015: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
IL_001a: stloc.2
~IL_001b: ldloca.s V_2
IL_001d: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
IL_0022: brtrue.s IL_0064
IL_0024: ldarg.0
IL_0025: ldc.i4.0
IL_0026: dup
IL_0027: stloc.0
IL_0028: stfld ""int C.<F>d__0.<>1__state""
<IL_002d: ldarg.0
IL_002e: ldloc.2
IL_002f: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.<F>d__0.<>u__1""
IL_0034: ldarg.0
IL_0035: stloc.3
IL_0036: ldarg.0
IL_0037: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_003c: ldloca.s V_2
IL_003e: ldloca.s V_3
IL_0040: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<F>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<F>d__0)""
IL_0045: nop
IL_0046: leave.s IL_00a7
>IL_0048: ldarg.0
IL_0049: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.<F>d__0.<>u__1""
IL_004e: stloc.2
IL_004f: ldarg.0
IL_0050: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.<F>d__0.<>u__1""
IL_0055: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
IL_005b: ldarg.0
IL_005c: ldc.i4.m1
IL_005d: dup
IL_005e: stloc.0
IL_005f: stfld ""int C.<F>d__0.<>1__state""
IL_0064: ldloca.s V_2
IL_0066: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
IL_006b: nop
IL_006c: ldloca.s V_2
IL_006e: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
-IL_0074: ldc.i4.1
IL_0075: stloc.1
IL_0076: leave.s IL_0092
}
catch System.Exception
{
~IL_0078: stloc.s V_4
IL_007a: ldarg.0
IL_007b: ldc.i4.s -2
IL_007d: stfld ""int C.<F>d__0.<>1__state""
IL_0082: ldarg.0
IL_0083: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_0088: ldloc.s V_4
IL_008a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
IL_008f: nop
IL_0090: leave.s IL_00a7
}
-IL_0092: ldarg.0
IL_0093: ldc.i4.s -2
IL_0095: stfld ""int C.<F>d__0.<>1__state""
~IL_009a: ldarg.0
IL_009b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__0.<>t__builder""
IL_00a0: ldloc.1
IL_00a1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
IL_00a6: nop
IL_00a7: ret
}
", sequencePoints: "C+<F>d__0.MoveNext");
}
[WorkItem(836491, "DevDiv")]
[WorkItem(827337, "DevDiv")]
[Fact]
......
......@@ -164,34 +164,33 @@ IEnumerable<int> M()
<namespace usingCount=""1"" />
</using>
<hoistedLocalScopes>
<slot startOffset=""0x22"" endOffset=""0x6a"" />
<slot startOffset=""0x20"" endOffset=""0x66"" />
</hoistedLocalScopes>
<encLocalSlotMap>
<slot kind=""27"" offset=""0"" />
<slot kind=""temp"" />
<slot kind=""temp"" />
<slot kind=""1"" offset=""37"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" hidden=""true"" document=""0"" />
<entry offset=""0x21"" startLine=""7"" startColumn=""5"" endLine=""7"" endColumn=""6"" document=""0"" />
<entry offset=""0x22"" startLine=""9"" startColumn=""14"" endLine=""9"" endColumn=""23"" document=""0"" />
<entry offset=""0x29"" hidden=""true"" document=""0"" />
<entry offset=""0x2b"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""10"" document=""0"" />
<entry offset=""0x2c"" startLine=""12"" startColumn=""13"" endLine=""12"" endColumn=""36"" document=""0"" />
<entry offset=""0x45"" hidden=""true"" document=""0"" />
<entry offset=""0x4c"" startLine=""13"" startColumn=""9"" endLine=""13"" endColumn=""10"" document=""0"" />
<entry offset=""0x4d"" startLine=""9"" startColumn=""33"" endLine=""9"" endColumn=""36"" document=""0"" />
<entry offset=""0x5d"" startLine=""9"" startColumn=""25"" endLine=""9"" endColumn=""31"" document=""0"" />
<entry offset=""0x68"" hidden=""true"" document=""0"" />
<entry offset=""0x6b"" startLine=""14"" startColumn=""5"" endLine=""14"" endColumn=""6"" document=""0"" />
<entry offset=""0x1f"" startLine=""7"" startColumn=""5"" endLine=""7"" endColumn=""6"" document=""0"" />
<entry offset=""0x20"" startLine=""9"" startColumn=""14"" endLine=""9"" endColumn=""23"" document=""0"" />
<entry offset=""0x27"" hidden=""true"" document=""0"" />
<entry offset=""0x29"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""10"" document=""0"" />
<entry offset=""0x2a"" startLine=""12"" startColumn=""13"" endLine=""12"" endColumn=""36"" document=""0"" />
<entry offset=""0x41"" hidden=""true"" document=""0"" />
<entry offset=""0x48"" startLine=""13"" startColumn=""9"" endLine=""13"" endColumn=""10"" document=""0"" />
<entry offset=""0x49"" startLine=""9"" startColumn=""33"" endLine=""9"" endColumn=""36"" document=""0"" />
<entry offset=""0x59"" startLine=""9"" startColumn=""25"" endLine=""9"" endColumn=""31"" document=""0"" />
<entry offset=""0x64"" hidden=""true"" document=""0"" />
<entry offset=""0x67"" startLine=""14"" startColumn=""5"" endLine=""14"" endColumn=""6"" document=""0"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0x6f"">
<scope startOffset=""0x0"" endOffset=""0x69"">
<namespace name=""System.Collections.Generic"" />
<scope startOffset=""0x21"" endOffset=""0x6f"">
<scope startOffset=""0x1f"" endOffset=""0x69"">
<constant name=""x"" value=""1"" type=""Int32"" />
<scope startOffset=""0x2b"" endOffset=""0x4d"">
<scope startOffset=""0x29"" endOffset=""0x49"">
<constant name=""y"" value=""2"" type=""Int32"" />
</scope>
</scope>
......
......@@ -505,7 +505,7 @@ public static void Main(string[] args)
</dynamicLocals>
<encLocalSlotMap>
<slot kind=""0"" offset=""23"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -602,7 +602,7 @@ public static void Main(string[] args)
</dynamicLocals>
<encLocalSlotMap>
<slot kind=""0"" offset=""19"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -667,7 +667,7 @@ public static void Main(string[] args)
</dynamicLocals>
<encLocalSlotMap>
<slot kind=""0"" offset=""23"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -849,7 +849,7 @@ public static void Main()
</dynamicLocals>
<encLocalSlotMap>
<slot kind=""0"" offset=""23"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -888,7 +888,7 @@ public static void Main()
</dynamicLocals>
<encLocalSlotMap>
<slot kind=""0"" offset=""19"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -1003,6 +1003,9 @@ public static void Main(string[] args)
<method containingType=""Test+&lt;&gt;c"" name=""&lt;Main&gt;b__2_2"" parameterNames=""d6"">
<customDebugInfo>
<forward declaringType=""Test"" methodName=""Main"" parameterNames=""args"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""125"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""11"" startColumn=""35"" endLine=""11"" endColumn=""36"" document=""0"" />
......
......@@ -107,7 +107,7 @@ static public int M(int p)
</using>
<encLocalSlotMap>
<slot kind=""1"" offset=""12"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -128,7 +128,7 @@ static public int M(int p)
<encLocalSlotMap>
<slot kind=""30"" offset=""0"" />
<slot kind=""0"" offset=""26"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
<encLambdaMap>
<methodOrdinal>1</methodOrdinal>
......@@ -155,7 +155,7 @@ static public int M(int p)
<encLocalSlotMap>
<slot kind=""30"" offset=""56"" />
<slot kind=""0"" offset=""110"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""56"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -173,6 +173,9 @@ static public int M(int p)
<method containingType=""Test+&lt;&gt;c__DisplayClass1_1"" name=""&lt;M&gt;b__1"" parameterNames=""y"">
<customDebugInfo>
<forward declaringType=""Test"" methodName=""Main"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""136"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""18"" startColumn=""13"" endLine=""18"" endColumn=""14"" document=""0"" />
......@@ -278,7 +281,7 @@ static public int M(int p)
</using>
<encLocalSlotMap>
<slot kind=""1"" offset=""11"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -299,7 +302,7 @@ static public int M(int p)
<encLocalSlotMap>
<slot kind=""30"" offset=""0"" />
<slot kind=""0"" offset=""26"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
<encLambdaMap>
<methodOrdinal>1</methodOrdinal>
......@@ -326,7 +329,7 @@ static public int M(int p)
<encLocalSlotMap>
<slot kind=""30"" offset=""56"" />
<slot kind=""0"" offset=""110"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""56"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -344,6 +347,9 @@ static public int M(int p)
<method containingType=""Test+&lt;&gt;c__DisplayClass1_1"" name=""&lt;M&gt;b__1"" parameterNames=""y"">
<customDebugInfo>
<forward declaringType=""Test"" methodName=""Main"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""122"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""17"" startColumn=""40"" endLine=""17"" endColumn=""41"" document=""0"" />
......
......@@ -291,7 +291,7 @@ class C
<encLocalSlotMap>
<slot kind=""0"" offset=""-118"" />
<slot kind=""0"" offset=""-54"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""-147"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -319,14 +319,13 @@ class C
<forward declaringType=""C"" methodName="".cctor"" />
<encLocalSlotMap>
<slot kind=""30"" offset=""-45"" />
<slot kind=""temp"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""61"" endLine=""7"" endColumn=""70"" document=""0"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0x1e"">
<local name=""CS$&lt;&gt;8__locals0"" il_index=""0"" il_start=""0x0"" il_end=""0x1e"" attributes=""0"" />
<scope startOffset=""0x0"" endOffset=""0x1a"">
<local name=""CS$&lt;&gt;8__locals0"" il_index=""0"" il_start=""0x0"" il_end=""0x1a"" attributes=""0"" />
</scope>
</method>
</methods>
......@@ -465,6 +464,241 @@ class C2
#endregion
#region ReturnStatement
[Fact]
public void Return_Method1()
{
var source = @"
class Program
{
static int Main()
{
return 1;
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// In order to place a breakpoint on the closing brace we need to save the return expression value to
// a local and then load it again (since sequence point needs an empty stack). This variable has to be marked as long-lived.
v.VerifyIL("Program.Main", @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
-IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
-IL_0005: ldloc.0
IL_0006: ret
}", sequencePoints: "Program.Main");
v.VerifyPdb("Program.Main", @"
<symbols>
<methods>
<method containingType=""Program"" name=""Main"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""5"" startColumn=""5"" endLine=""5"" endColumn=""6"" document=""0"" />
<entry offset=""0x1"" startLine=""6"" startColumn=""9"" endLine=""6"" endColumn=""18"" document=""0"" />
<entry offset=""0x5"" startLine=""7"" startColumn=""5"" endLine=""7"" endColumn=""6"" document=""0"" />
</sequencePoints>
</method>
</methods>
</symbols>");
}
[Fact]
public void Return_Property1()
{
var source = @"
class C
{
static int P
{
get { return 1; }
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// In order to place a breakpoint on the closing brace we need to save the return expression value to
// a local and then load it again (since sequence point needs an empty stack). This variable has to be marked as long-lived.
v.VerifyIL("C.P.get", @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
-IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
-IL_0005: ldloc.0
IL_0006: ret
}", sequencePoints: "C.get_P");
v.VerifyPdb("C.get_P", @"
<symbols>
<methods>
<method containingType=""C"" name=""get_P"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""6"" startColumn=""13"" endLine=""6"" endColumn=""14"" document=""0"" />
<entry offset=""0x1"" startLine=""6"" startColumn=""15"" endLine=""6"" endColumn=""24"" document=""0"" />
<entry offset=""0x5"" startLine=""6"" startColumn=""25"" endLine=""6"" endColumn=""26"" document=""0"" />
</sequencePoints>
</method>
</methods>
</symbols>");
}
[Fact]
public void Return_Void1()
{
var source = @"
class Program
{
static void Main()
{
return;
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 4 (0x4)
.maxstack 0
-IL_0000: nop
-IL_0001: br.s IL_0003
-IL_0003: ret
}", sequencePoints: "Program.Main");
}
[Fact]
public void Return_ExpressionBodied1()
{
var source = @"
class Program
{
static int Main() => 1;
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 2 (0x2)
.maxstack 1
-IL_0000: ldc.i4.1
IL_0001: ret
}", sequencePoints: "Program.Main");
}
[Fact]
public void Return_FromExceptionHandler1()
{
var source = @"
using System;
class Program
{
static int Main()
{
try
{
Console.WriteLine();
return 1;
}
catch (Exception)
{
return 2;
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 20 (0x14)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
.try
{
-IL_0001: nop
-IL_0002: call ""void System.Console.WriteLine()""
IL_0007: nop
-IL_0008: ldc.i4.1
IL_0009: stloc.0
IL_000a: leave.s IL_0012
}
catch System.Exception
{
-IL_000c: pop
-IL_000d: nop
-IL_000e: ldc.i4.2
IL_000f: stloc.0
IL_0010: leave.s IL_0012
}
-IL_0012: ldloc.0
IL_0013: ret
}", sequencePoints: "Program.Main");
v.VerifyPdb("Program.Main", @"
<symbols>
<methods>
<method containingType=""Program"" name=""Main"">
<customDebugInfo>
<using>
<namespace usingCount=""1"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""5"" endLine=""7"" endColumn=""6"" document=""0"" />
<entry offset=""0x1"" startLine=""9"" startColumn=""9"" endLine=""9"" endColumn=""10"" document=""0"" />
<entry offset=""0x2"" startLine=""10"" startColumn=""13"" endLine=""10"" endColumn=""33"" document=""0"" />
<entry offset=""0x8"" startLine=""11"" startColumn=""13"" endLine=""11"" endColumn=""22"" document=""0"" />
<entry offset=""0xc"" startLine=""13"" startColumn=""9"" endLine=""13"" endColumn=""26"" document=""0"" />
<entry offset=""0xd"" startLine=""14"" startColumn=""9"" endLine=""14"" endColumn=""10"" document=""0"" />
<entry offset=""0xe"" startLine=""15"" startColumn=""13"" endLine=""15"" endColumn=""22"" document=""0"" />
<entry offset=""0x12"" startLine=""17"" startColumn=""5"" endLine=""17"" endColumn=""6"" document=""0"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0x14"">
<namespace name=""System"" />
</scope>
</method>
</methods>
</symbols>");
}
#endregion
#region IfStatement
[Fact]
......@@ -1517,7 +1751,7 @@ public static int Main()
<slot kind=""0"" offset=""29"" />
<slot kind=""0"" offset=""56"" />
<slot kind=""0"" offset=""126"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -2122,7 +2356,7 @@ public static string ReturnValue(int p)
<slot kind=""1"" offset=""138"" />
<slot kind=""1"" offset=""238"" />
<slot kind=""1"" offset=""330"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -2184,7 +2418,7 @@ public static string ReturnValue(int p)
<encLocalSlotMap>
<slot kind=""0"" offset=""15"" />
<slot kind=""1"" offset=""42"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......@@ -2257,7 +2491,7 @@ static int Main()
<encLocalSlotMap>
<slot kind=""0"" offset=""15"" />
<slot kind=""0"" offset=""147"" />
<slot kind=""temp"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
......
......@@ -1454,6 +1454,9 @@ class C
<method containingType=""C+&lt;&gt;c"" name=""&lt;.ctor&gt;b__2_0"" parameterNames=""x"">
<customDebugInfo>
<forward declaringType=""C"" methodName="".ctor"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""-23"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""6"" startColumn=""35"" endLine=""6"" endColumn=""36"" document=""0"" />
......@@ -1464,6 +1467,9 @@ class C
<method containingType=""C+&lt;&gt;c"" name=""&lt;.cctor&gt;b__3_0"" parameterNames=""x"">
<customDebugInfo>
<forward declaringType=""C"" methodName="".ctor"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""-38"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""8"" startColumn=""5"" endLine=""8"" endColumn=""6"" document=""0"" />
......@@ -1509,6 +1515,9 @@ class C
<using>
<namespace usingCount=""1"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""18"" endLine=""7"" endColumn=""19"" document=""0"" />
......@@ -1549,6 +1558,9 @@ class C
<method containingType=""C"" name=""get_Item"" parameterNames=""x"">
<customDebugInfo>
<forward declaringType=""C"" methodName=""get_P2"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""8"" startColumn=""27"" endLine=""8"" endColumn=""28"" document=""0"" />
......@@ -1649,6 +1661,9 @@ class C : I1, I2
<using>
<namespace usingCount=""1"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""18"" startColumn=""34"" endLine=""18"" endColumn=""35"" document=""0"" />
......
......@@ -128,7 +128,8 @@ internal enum SynthesizedLocalKind
StateMachineReturnValue = AsyncMethodReturnValue, // TODO VB: why do we need this in iterators?
/// <summary>
/// Stores the return value of a VB function that is not accessible from user code (e.g. operator, lambda, async, iterator).
/// VB: Stores the return value of a function that is not accessible from user code (e.g. operator, lambda, async, iterator).
/// C#: Stores the return value of a method/lambda with a block body, so that we can put a sequence point on the closing brace of the body.
/// </summary>
FunctionReturnValue = 21,
......
......@@ -4628,8 +4628,7 @@ System.Collections.IEnumerable F(int x)
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__0.x""
IL_0006: ret
......@@ -4667,12 +4666,11 @@ System.Collections.IEnumerable F(int x)
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.<F>d__0.<t>5__1""
IL_0006: ret
}
}
");
}
......@@ -5342,7 +5340,6 @@ static void M(object x, object y)
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (bool V_0)
IL_0000: ldarg.1
IL_0001: ret
}");
......@@ -5379,7 +5376,6 @@ static void M()
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (bool V_0)
IL_0000: ldarg.1
IL_0001: ret
}");
......@@ -5488,8 +5484,7 @@ static IEnumerable<T> I<T>(T[] tt)
{
// Code size 11 (0xb)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldtoken ""T""
IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_000a: ret
......
......@@ -98,8 +98,7 @@ static void DummySequencePoint()
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1,
int V_2)
int V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__0.{0}""
IL_0006: ret
......
......@@ -35,8 +35,7 @@ System.Collections.IEnumerable F()
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<F>d__0.<>4__this""
IL_0006: ret
......@@ -137,8 +136,7 @@ System.Collections.IEnumerable F()
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<F>d__0.<>4__this""
IL_0006: ret
......@@ -248,8 +246,7 @@ System.Collections.IEnumerable F<U>()
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C<T> C<T>.<F>d__0<U>.<>4__this""
IL_0006: ret
......@@ -337,8 +334,7 @@ System.Collections.IEnumerable I.F()
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<I-F>d__0.<>4__this""
IL_0006: ret
......@@ -436,8 +432,7 @@ System.Collections.IEnumerable I<int>.F()
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<I<System-Int32>-F>d__0.<>4__this""
IL_0006: ret
......@@ -866,7 +861,6 @@ int P
{{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.{0}.<>4__this""
IL_0006: ret
......@@ -1052,8 +1046,7 @@ System.Collections.IEnumerable F()
{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<F>d__1.<>4__this""
IL_0006: ldfld ""object C.x""
......@@ -1165,8 +1158,7 @@ System.Collections.IEnumerable M()
{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0,
bool V_1)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""Derived Derived.<M>d__1.<>4__this""
IL_0006: ldfld ""int Base.x""
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册