Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
d1237c0d
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d1237c0d
编写于
3月 07, 2018
作者:
N
Neal Gafter
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve dag construction to improve generated code.
上级
bfdde8d3
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1041 addition
and
1154 deletion
+1041
-1154
src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs
src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs
+137
-7
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BasePatternSwitchLocalRewriter.cs
...lRewriter/LocalRewriter_BasePatternSwitchLocalRewriter.cs
+1
-0
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Patterns.cs
...Portable/Lowering/LocalRewriter/LocalRewriter_Patterns.cs
+1
-1
src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
+116
-104
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
+424
-617
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs
...rp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs
+47
-47
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
...p/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
+213
-227
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
+102
-151
未找到文件。
src/Compilers/CSharp/Portable/Binder/DecisionDagBuilder.cs
浏览文件 @
d1237c0d
...
...
@@ -524,13 +524,7 @@ DagState uniqifyState(DagState state)
}
else
{
BoundDagDecision
selectDecision
(
DagState
s
)
{
// Our simple heuristic is to perform the first test of the first possible matched case
return
s
.
Cases
[
0
].
Decisions
[
0
];
}
switch
(
state
.
SelectedDecision
=
selectDecision
(
state
))
switch
(
state
.
SelectedDecision
=
state
.
ComputeSelectedDecision
())
{
case
BoundDagEvaluation
e
:
state
.
TrueBranch
=
uniqifyState
(
RemoveEvaluation
(
state
.
Cases
,
e
));
...
...
@@ -643,6 +637,7 @@ BoundDecisionDag finalState(SyntaxNode syntax, LabelSymbol label, ImmutableArray
finalStates
.
Free
();
Debug
.
Assert
(
initialState
.
Dag
!=
null
);
// Note: It is useful for debugging the dag state table construction to view `initialState.Dump()` here.
return
initialState
.
Dag
;
}
...
...
@@ -775,6 +770,10 @@ BoundDecisionDag finalState(SyntaxNode syntax, LabelSymbol label, ImmutableArray
trueDecisionPermitsTrueOther
=
false
;
// if v!=null is true, then v==null cannot succeed
falseDecisionImpliesTrueOther
=
true
;
// if v!=null is false, then v==null has been proven true
break
;
case
BoundNonNullDecision
n2
:
trueDecisionImpliesTrueOther
=
true
;
falseDecisionPermitsTrueOther
=
false
;
break
;
default
:
// Once v!=null fails, it must fail a type test
falseDecisionPermitsTrueOther
=
false
;
...
...
@@ -885,6 +884,10 @@ private static PartialCaseDecision RemoveEvaluation(PartialCaseDecision c, Bound
Bindings
:
c
.
Bindings
,
WhenClause
:
c
.
WhenClause
,
CaseLabel
:
c
.
CaseLabel
);
}
/// <summary>
/// The state at a given node of the decision acyclic graph. This is used during computation of the state machine,
/// and contains a representation of the meaning of the state.
/// </summary>
private
class
DagState
{
public
readonly
ImmutableArray
<
PartialCaseDecision
>
Cases
;
...
...
@@ -904,7 +907,134 @@ public DagState(ImmutableArray<PartialCaseDecision> cases)
// After the entire graph of DagState objects is complete, we translate each into its Dag.
public
BoundDecisionDag
Dag
;
// Compute a decision to use at the root of the generated decision tree.
internal
BoundDagDecision
ComputeSelectedDecision
()
{
// Our simple heuristic is to perform the first test of the first possible matched case
var
choice
=
Cases
[
0
].
Decisions
[
0
];
// But if that test is a null check, it would be redundant with a following
// type test. We apply this refinement only when there is exactly one case, because
// when there are multiple cases the null check is likely to be shared.
if
(
choice
.
Kind
==
BoundKind
.
NonNullDecision
&&
Cases
.
Length
==
1
&&
Cases
[
0
].
Decisions
.
Length
>
1
)
{
var
choice2
=
Cases
[
0
].
Decisions
[
1
];
if
(
choice2
.
Kind
==
BoundKind
.
TypeDecision
)
{
return
choice2
;
}
}
return
choice
;
}
#if DEBUG
/// <summary>
/// Starting with `this` state, produce a human-readable description of the state tables.
/// This is very useful for debugging and optimizing the dag state construction.
/// </summary>
internal
string
Dump
()
{
var
printed
=
PooledHashSet
<
DagState
>.
GetInstance
();
int
nextStateNumber
=
0
;
var
workQueue
=
ArrayBuilder
<
DagState
>.
GetInstance
();
var
stateIdentifierMap
=
PooledDictionary
<
DagState
,
int
>.
GetInstance
();
int
stateIdentifier
(
DagState
state
)
{
if
(
stateIdentifierMap
.
TryGetValue
(
state
,
out
int
value
))
{
return
value
;
}
else
{
value
=
stateIdentifierMap
[
state
]
=
++
nextStateNumber
;
workQueue
.
Push
(
state
);
}
return
value
;
}
int
nextTempNumber
=
0
;
var
tempIdentifierMap
=
PooledDictionary
<
BoundDagEvaluation
,
int
>.
GetInstance
();
int
tempIdentifier
(
BoundDagEvaluation
e
)
{
return
(
e
==
null
)
?
0
:
tempIdentifierMap
.
TryGetValue
(
e
,
out
int
value
)
?
value
:
tempIdentifierMap
[
e
]
=
++
nextTempNumber
;
}
string
tempName
(
BoundDagTemp
t
)
{
return
$"t
{
tempIdentifier
(
t
.
Source
)}{(
t
.
Index
!=
0
?
$".
{
t
.
Index
.
ToString
()}
"
:
""
)}
"
;
}
var
resultBuilder
=
PooledStringBuilder
.
GetInstance
();
var
result
=
resultBuilder
.
Builder
;
stateIdentifier
(
this
);
// push the start node onto the work queue
while
(
workQueue
.
Count
!=
0
)
{
var
state
=
workQueue
.
Pop
();
if
(!
printed
.
Add
(
state
))
{
continue
;
}
result
.
AppendLine
(
$"State "
+
stateIdentifier
(
state
));
foreach
(
PartialCaseDecision
cd
in
state
.
Cases
)
{
result
.
Append
(
$" [
{
cd
.
Syntax
}
]"
);
foreach
(
BoundDagDecision
d
in
cd
.
Decisions
)
{
result
.
Append
(
$"
{
dump
(
d
)}
"
);
}
result
.
AppendLine
();
}
if
(
state
.
SelectedDecision
!=
null
)
{
result
.
AppendLine
(
$" Decision:
{
dump
(
state
.
SelectedDecision
)}
"
);
}
if
(
state
.
TrueBranch
!=
null
)
{
result
.
AppendLine
(
$" TrueBranch:
{
stateIdentifier
(
state
.
TrueBranch
)}
"
);
}
if
(
state
.
FalseBranch
!=
null
)
{
result
.
AppendLine
(
$" FalseBranch:
{
stateIdentifier
(
state
.
FalseBranch
)}
"
);
}
}
workQueue
.
Free
();
printed
.
Free
();
stateIdentifierMap
.
Free
();
tempIdentifierMap
.
Free
();
return
resultBuilder
.
ToStringAndFree
();
string
dump
(
BoundDagDecision
d
)
{
switch
(
d
)
{
case
BoundDagTypeEvaluation
a
:
return
$"t
{
tempIdentifier
(
a
)}
=
{
a
.
Kind
}
(
{
a
.
Type
.
ToString
()}
)"
;
case
BoundDagEvaluation
e
:
return
$"t
{
tempIdentifier
(
e
)}
=
{
e
.
Kind
}
"
;
case
BoundTypeDecision
b
:
return
$"?
{
d
.
Kind
}
(
{
b
.
Type
.
ToString
()}
,
{
tempName
(
d
.
Input
)}
)"
;
case
BoundNonNullValueDecision
v
:
return
$"?
{
d
.
Kind
}
(
{
v
.
Value
.
ToString
()}
,
{
tempName
(
d
.
Input
)}
)"
;
default
:
return
$"?
{
d
.
Kind
}
(
{
tempName
(
d
.
Input
)}
)"
;
}
}
}
}
#endif
/// <summary>
/// An equivalence relation between dag states used to dedup the states during dag construction.
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BasePatternSwitchLocalRewriter.cs
浏览文件 @
d1237c0d
...
...
@@ -149,6 +149,7 @@ private void LowerDecisionDag(ImmutableArray<BoundDecisionDag> sortedNodes)
/// <summary>
/// Translate the decision tree for node, given that it will be followed by the translation for nextNode.
/// This knowledge allows us to fall through to nextNode instead of producing a goto statement to get there.
/// </summary>
private
void
LowerDecisionDagNode
(
BoundDecisionDag
node
,
BoundDecisionDag
nextNode
)
{
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Patterns.cs
浏览文件 @
d1237c0d
...
...
@@ -203,7 +203,6 @@ protected BoundExpression LowerDecision(BoundDagDecision decision)
}
else
{
// PROTOTYPE(patterns2): combine null test and type test when possible for improved code
return
_localRewriter
.
MakeNullCheck
(
d
.
Syntax
,
input
,
input
.
Type
.
IsNullableType
()
?
BinaryOperatorKind
.
NullableNullNotEqual
:
BinaryOperatorKind
.
NotEqual
);
}
...
...
@@ -211,6 +210,7 @@ protected BoundExpression LowerDecision(BoundDagDecision decision)
case
BoundTypeDecision
d
:
{
// Note that this tests for non-null as a side-effect. We depend on that to sometimes avoid the null check.
return
_factory
.
Is
(
input
,
d
.
Type
);
}
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs
浏览文件 @
d1237c0d
...
...
@@ -142,7 +142,6 @@ static void M1(int? x)
);
}
// PROTOTYPE(patterns2): code quality has regressed for this test because the lowering strategy reifies the boolean result of the if expression.
[
Fact
,
WorkItem
(
17266
,
"https://github.com/dotnet/roslyn/issues/17266"
)]
public
void
DoubleEvaluation01
()
{
...
...
@@ -200,6 +199,28 @@ .maxstack 1
IL_002a: nop
IL_002b: ret
}"
);
compilation
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
compilation
.
VerifyDiagnostics
();
compVerifier
=
CompileAndVerify
(
compilation
,
expectedOutput
:
expectedOutput
);
compVerifier
.
VerifyIL
(
"C.Main"
,
@"{
// Code size 30 (0x1e)
.maxstack 1
.locals init (int V_0, //index
int? V_1)
IL_0000: call ""int? C.TryGet()""
IL_0005: stloc.1
IL_0006: ldloca.s V_1
IL_0008: call ""bool int?.HasValue.get""
IL_000d: brfalse.s IL_001d
IL_000f: ldloca.s V_1
IL_0011: call ""int int?.GetValueOrDefault()""
IL_0016: stloc.0
IL_0017: ldloc.0
IL_0018: call ""void System.Console.WriteLine(int)""
IL_001d: ret
}"
);
}
[
Fact
,
WorkItem
(
19122
,
"https://github.com/dotnet/roslyn/issues/19122"
)]
...
...
@@ -248,7 +269,7 @@ public Guid GetId(T t)
var
compVerifier
=
CompileAndVerify
(
compilation
);
compVerifier
.
VerifyIL
(
"X<T>.Y<U>"
,
@"{
// Code size
71 (0x47
)
// Code size
63 (0x3f
)
.maxstack 3
.locals init (U V_0, //u
bool V_1,
...
...
@@ -264,26 +285,23 @@ .maxstack 3
IL_0018: stloc.2
IL_0019: ldloc.2
IL_001a: box ""T""
IL_001f: brfalse.s IL_003f
IL_0021: ldloc.2
IL_0022: box ""T""
IL_0027: isinst ""U""
IL_002c: brfalse.s IL_003f
IL_002e: ldloc.2
IL_002f: box ""T""
IL_0034: unbox.any ""U""
IL_0039: stloc.3
IL_003a: ldloc.3
IL_003b: stloc.0
IL_003c: ldc.i4.1
IL_003d: br.s IL_0040
IL_003f: ldc.i4.0
IL_0040: stloc.1
IL_0041: ldloc.1
IL_0042: brfalse.s IL_0046
IL_0044: nop
IL_0045: nop
IL_0046: ret
IL_001f: isinst ""U""
IL_0024: brfalse.s IL_0037
IL_0026: ldloc.2
IL_0027: box ""T""
IL_002c: unbox.any ""U""
IL_0031: stloc.3
IL_0032: ldloc.3
IL_0033: stloc.0
IL_0034: ldc.i4.1
IL_0035: br.s IL_0038
IL_0037: ldc.i4.0
IL_0038: stloc.1
IL_0039: ldloc.1
IL_003a: brfalse.s IL_003e
IL_003c: nop
IL_003d: nop
IL_003e: ret
}"
);
}
...
...
@@ -327,7 +345,7 @@ static void Main(string[] args)
var
compVerifier
=
CompileAndVerify
(
compilation
,
expectedOutput
:
expectedOutput
);
compVerifier
.
VerifyIL
(
"Program.Main"
,
@"{
// Code size 1
13 (0x71
)
// Code size 1
06 (0x6a
)
.maxstack 2
.locals init (Base<object> V_0, //x
Derived V_1, //y
...
...
@@ -346,47 +364,43 @@ .maxstack 2
IL_0010: call ""void System.Console.WriteLine(bool)""
IL_0015: nop
IL_0016: ldloc.0
IL_0017: brfalse.s IL_002d
IL_0019: ldloc.0
IL_001a: isinst ""Derived""
IL_001f: brfalse.s IL_002d
IL_0021: ldloc.0
IL_0022: castclass ""Derived""
IL_0027: stloc.2
IL_0028: ldloc.2
IL_0029: stloc.1
IL_002a: ldc.i4.1
IL_002b: br.s IL_002e
IL_002d: ldc.i4.0
IL_002e: call ""void System.Console.WriteLine(bool)""
IL_0033: nop
IL_0034: ldloc.0
IL_0035: stloc.s V_6
IL_0037: ldloc.s V_6
IL_0039: stloc.s V_4
IL_003b: ldloc.s V_4
IL_003d: brfalse.s IL_0061
IL_003f: ldloc.s V_4
IL_0041: isinst ""Derived""
IL_0046: brfalse.s IL_0061
IL_0048: ldloc.s V_4
IL_004a: castclass ""Derived""
IL_004f: stloc.s V_5
IL_0051: br.s IL_0053
IL_0053: ldloc.s V_5
IL_0055: stloc.3
IL_0056: br.s IL_0058
IL_0058: ldc.i4.1
IL_0059: call ""void System.Console.WriteLine(bool)""
IL_005e: nop
IL_005f: br.s IL_0061
IL_0061: ldloc.0
IL_0062: isinst ""Derived""
IL_0067: ldnull
IL_0068: cgt.un
IL_006a: call ""void System.Console.WriteLine(bool)""
IL_006f: nop
IL_0070: ret
IL_0017: isinst ""Derived""
IL_001c: brfalse.s IL_002a
IL_001e: ldloc.0
IL_001f: castclass ""Derived""
IL_0024: stloc.2
IL_0025: ldloc.2
IL_0026: stloc.1
IL_0027: ldc.i4.1
IL_0028: br.s IL_002b
IL_002a: ldc.i4.0
IL_002b: call ""void System.Console.WriteLine(bool)""
IL_0030: nop
IL_0031: ldloc.0
IL_0032: stloc.s V_6
IL_0034: ldloc.s V_6
IL_0036: stloc.s V_4
IL_0038: ldloc.s V_4
IL_003a: isinst ""Derived""
IL_003f: brfalse.s IL_005a
IL_0041: ldloc.s V_4
IL_0043: castclass ""Derived""
IL_0048: stloc.s V_5
IL_004a: br.s IL_004c
IL_004c: ldloc.s V_5
IL_004e: stloc.3
IL_004f: br.s IL_0051
IL_0051: ldc.i4.1
IL_0052: call ""void System.Console.WriteLine(bool)""
IL_0057: nop
IL_0058: br.s IL_005a
IL_005a: ldloc.0
IL_005b: isinst ""Derived""
IL_0060: ldnull
IL_0061: cgt.un
IL_0063: call ""void System.Console.WriteLine(bool)""
IL_0068: nop
IL_0069: ret
}"
);
}
...
...
@@ -472,7 +486,7 @@ .maxstack 2
}"
);
compVerifier
.
VerifyIL
(
"Program.P5"
,
@"{
// Code size 12
5 (0x7d
)
// Code size 12
2 (0x7a
)
.maxstack 2
.locals init (object V_0,
double V_1,
...
...
@@ -485,7 +499,7 @@ .maxstack 2
IL_0003: ldloc.3
IL_0004: stloc.0
IL_0005: ldloc.0
IL_0006: brfalse.s IL_007
5
IL_0006: brfalse.s IL_007
2
IL_0008: ldloc.0
IL_0009: isinst ""double""
IL_000e: brfalse.s IL_0035
...
...
@@ -494,49 +508,47 @@ .maxstack 2
IL_0016: stloc.1
IL_0017: ldloc.1
IL_0018: call ""bool double.IsNaN(double)""
IL_001d: brtrue.s IL_00
61
IL_001d: brtrue.s IL_00
5e
IL_001f: ldloc.0
IL_0020: isinst ""double""
IL_0025: brfalse.s IL_007
5
IL_0025: brfalse.s IL_007
2
IL_0027: ldc.r8 3.14
IL_0030: ldloc.1
IL_0031: beq.s IL_006
b
IL_0033: br.s IL_007
5
IL_0031: beq.s IL_006
8
IL_0033: br.s IL_007
2
IL_0035: ldloc.0
IL_0036: brfalse.s IL_0075
IL_0038: ldloc.0
IL_0039: isinst ""float""
IL_003e: brfalse.s IL_0075
IL_0040: ldloc.0
IL_0041: unbox.any ""float""
IL_0046: stloc.2
IL_0047: ldloc.2
IL_0048: call ""bool float.IsNaN(float)""
IL_004d: brtrue.s IL_0066
IL_004f: ldloc.0
IL_0050: isinst ""float""
IL_0055: brfalse.s IL_0075
IL_0057: ldc.r4 3.14
IL_005c: ldloc.2
IL_005d: beq.s IL_0070
IL_005f: br.s IL_0075
IL_0061: ldc.i4.1
IL_0062: stloc.s V_4
IL_0064: br.s IL_007a
IL_0066: ldc.i4.1
IL_0067: stloc.s V_4
IL_0069: br.s IL_007a
IL_006b: ldc.i4.1
IL_006c: stloc.s V_4
IL_006e: br.s IL_007a
IL_0070: ldc.i4.1
IL_0071: stloc.s V_4
IL_0073: br.s IL_007a
IL_0075: ldc.i4.0
IL_0076: stloc.s V_4
IL_0078: br.s IL_007a
IL_007a: ldloc.s V_4
IL_007c: ret
IL_0036: isinst ""float""
IL_003b: brfalse.s IL_0072
IL_003d: ldloc.0
IL_003e: unbox.any ""float""
IL_0043: stloc.2
IL_0044: ldloc.2
IL_0045: call ""bool float.IsNaN(float)""
IL_004a: brtrue.s IL_0063
IL_004c: ldloc.0
IL_004d: isinst ""float""
IL_0052: brfalse.s IL_0072
IL_0054: ldc.r4 3.14
IL_0059: ldloc.2
IL_005a: beq.s IL_006d
IL_005c: br.s IL_0072
IL_005e: ldc.i4.1
IL_005f: stloc.s V_4
IL_0061: br.s IL_0077
IL_0063: ldc.i4.1
IL_0064: stloc.s V_4
IL_0066: br.s IL_0077
IL_0068: ldc.i4.1
IL_0069: stloc.s V_4
IL_006b: br.s IL_0077
IL_006d: ldc.i4.1
IL_006e: stloc.s V_4
IL_0070: br.s IL_0077
IL_0072: ldc.i4.0
IL_0073: stloc.s V_4
IL_0075: br.s IL_0077
IL_0077: ldloc.s V_4
IL_0079: ret
}"
);
}
}
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
浏览文件 @
d1237c0d
此差异已折叠。
点击以展开。
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueTests.cs
浏览文件 @
d1237c0d
...
...
@@ -7585,7 +7585,7 @@ .maxstack 2
"
);
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): code quality"
)
]
[
Fact
]
public
void
PatternVariable_TypeChange
()
{
var
source0
=
MarkedSource
(
@"
...
...
@@ -7617,19 +7617,19 @@ class C
v0
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 37 (0x25)
.maxstack
2
.maxstack
1
.locals init (int V_0, //i
bool V_1,
objec
t V_2,
in
t V_2,
int V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.2
IL_000
4: isinst ""int""
IL_000
9: brfalse.s IL_0015
IL_000
b: ld
loc.2
IL_00
0c: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_0015
IL_000
9: ldarg.0
IL_000
a: unbox.any ""int""
IL_000
f: st
loc.2
IL_00
10: ldloc.2
IL_0011: stloc.0
IL_0012: ldc.i4.1
IL_0013: br.s IL_0016
...
...
@@ -7659,23 +7659,23 @@ .maxstack 2
diff1
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 52 (0x34)
.maxstack
2
.maxstack
1
.locals init ([int] V_0,
[bool] V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
bool V_4, //i
bool V_5,
object
V_6,
bool
V_6,
int V_7)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.s V_6
IL_000
5: isinst ""bool""
IL_000a:
brfalse.s IL_0018
IL_000
c: ld
loc.s V_6
IL_00
0e: unbox.any ""bool""
IL_0002:
isinst ""bool""
IL_000
7: brfalse.s IL_0018
IL_000
9: ldarg.0
IL_000a:
unbox.any ""bool""
IL_000
f: st
loc.s V_6
IL_00
11: ldloc.s V_6
IL_0013: stloc.s V_4
IL_0015: ldc.i4.1
IL_0016: br.s IL_0019
...
...
@@ -7706,27 +7706,27 @@ .maxstack 2
diff2
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 46 (0x2e)
.maxstack
2
.maxstack
1
.locals init ([int] V_0,
[bool] V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
[bool] V_4,
[bool] V_5,
[
object
] V_6,
[
bool
] V_6,
[int] V_7,
int V_8, //j
bool V_9,
objec
t V_10,
in
t V_10,
int V_11)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.s V_10
IL_000
5: isinst ""int""
IL_000a:
brfalse.s IL_0018
IL_000
c: ld
loc.s V_10
IL_00
0e: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_0018
IL_000
9: ldarg.0
IL_000a:
unbox.any ""int""
IL_000
f: st
loc.s V_10
IL_00
11: ldloc.s V_10
IL_0013: stloc.s V_8
IL_0015: ldc.i4.1
IL_0016: br.s IL_0019
...
...
@@ -7746,7 +7746,7 @@ .maxstack 2
}"
);
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): code quality"
)
]
[
Fact
]
public
void
PatternVariable_DeleteInsert
()
{
var
source0
=
MarkedSource
(
@"
...
...
@@ -7778,19 +7778,19 @@ class C
v0
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 37 (0x25)
.maxstack
2
.maxstack
1
.locals init (int V_0, //i
bool V_1,
objec
t V_2,
in
t V_2,
int V_3)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.2
IL_000
4: isinst ""int""
IL_000
9: brfalse.s IL_0015
IL_000
b: ld
loc.2
IL_00
0c: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_0015
IL_000
9: ldarg.0
IL_000
a: unbox.any ""int""
IL_000
f: st
loc.2
IL_00
10: ldloc.2
IL_0011: stloc.0
IL_0012: ldc.i4.1
IL_0013: br.s IL_0016
...
...
@@ -7823,7 +7823,7 @@ .maxstack 2
.maxstack 2
.locals init ([int] V_0,
[bool] V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
bool V_4,
int V_5)
...
...
@@ -7855,25 +7855,25 @@ .maxstack 2
diff2
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 46 (0x2e)
.maxstack
2
.maxstack
1
.locals init ([int] V_0,
[bool] V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
[bool] V_4,
[int] V_5,
int V_6, //i
bool V_7,
objec
t V_8,
in
t V_8,
int V_9)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.s V_
8
IL_000
5: isinst ""int""
IL_000a:
brfalse.s IL_0018
IL_000
c: ld
loc.s V_8
IL_00
0e: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_001
8
IL_000
9: ldarg.0
IL_000a:
unbox.any ""int""
IL_000
f: st
loc.s V_8
IL_00
11: ldloc.s V_8
IL_0013: stloc.s V_6
IL_0015: ldc.i4.1
IL_0016: br.s IL_0019
...
...
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
浏览文件 @
d1237c0d
...
...
@@ -2364,7 +2364,7 @@ .locals init (int V_0)
}"
);
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): local slot mapping is not yet supported for new pattern switch"
)
]
[
Fact
]
public
void
Switch_Patterns
()
{
var
source
=
@"
...
...
@@ -2402,15 +2402,14 @@ static void M()
<customDebugInfo>
<forward declaringType=""C"" methodName=""F"" />
<encLocalSlotMap>
<slot kind=""35"" offset=""11"" />
<slot kind=""35"" offset=""11"" />
<slot kind=""35"" offset=""11"" />
<slot kind=""0"" offset=""106"" />
<slot kind=""0"" offset=""162"" />
<slot kind=""0"" offset=""273"" />
<slot kind=""0"" offset=""323"" />
<slot kind=""35"" offset=""19"" />
<slot kind=""35"" offset=""19"" />
<slot kind=""35"" offset=""19"" />
<slot kind=""1"" offset=""11"" />
<slot kind=""temp"" />
</encLocalSlotMap>
</customDebugInfo>
</method>
...
...
@@ -2419,107 +2418,95 @@ static void M()
v0
.
VerifyIL
(
"C.M"
,
@"
{
// Code size
200 (0xc8
)
// Code size
197 (0xc5
)
.maxstack 2
.locals init (object V_0,
int V_1,
byte V_2,
byte V_3, //b
int V_4, //i
int V_5, //j
object V_6, //o
object V_7,
object V_8)
.locals init (byte V_0, //b
int V_1, //i
int V_2, //j
object V_3, //o
object V_4,
int V_5,
byte V_6,
object V_7)
IL_0000: nop
IL_0001: call ""object C.F()""
IL_0006: stloc.s V_7
IL_0008: ldloc.s V_7
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: brtrue.s IL_0010
IL_000e: br.s IL_0063
IL_0010: ldloc.0
IL_0011: dup
IL_0012: stloc.s V_8
IL_0014: isinst ""int""
IL_0019: brfalse.s IL_002b
IL_001b: ldloc.s V_8
IL_001d: unbox.any ""int""
IL_0022: stloc.1
IL_0023: ldloc.1
IL_0024: ldc.i4.1
IL_0025: beq.s IL_0029
IL_0027: br.s IL_002b
IL_0029: br.s IL_0065
IL_002b: ldloc.0
IL_002c: dup
IL_002d: stloc.s V_8
IL_002f: isinst ""byte""
IL_0034: brfalse.s IL_0048
IL_0036: ldloc.s V_8
IL_0038: unbox.any ""byte""
IL_003d: stloc.2
IL_003e: br.s IL_0072
IL_0040: ldloc.2
IL_0041: ldc.i4.1
IL_0042: beq.s IL_0046
IL_0044: br.s IL_0048
IL_0046: br.s IL_009c
IL_0048: ldloc.0
IL_0049: dup
IL_004a: stloc.s V_8
IL_004c: isinst ""int""
IL_0051: brfalse.s IL_005f
IL_0053: ldloc.s V_8
IL_0055: unbox.any ""int""
IL_005a: stloc.1
IL_005b: br.s IL_0086
IL_005d: br.s IL_00a9
IL_005f: ldloc.0
IL_0060: stloc.0
IL_0061: br.s IL_00b8
IL_0063: br.s IL_00c7
IL_0065: ldstr ""int 1""
IL_006a: call ""void System.Console.WriteLine(string)""
IL_006f: nop
IL_0070: br.s IL_00c7
IL_0072: ldloc.2
IL_0073: stloc.3
IL_000a: stloc.s V_4
IL_000c: ldloc.s V_4
IL_000e: brfalse IL_00c4
IL_0013: ldloc.s V_4
IL_0015: isinst ""int""
IL_001a: brfalse.s IL_0040
IL_001c: ldloc.s V_4
IL_001e: unbox.any ""int""
IL_0023: stloc.s V_5
IL_0025: ldc.i4.1
IL_0026: ldloc.s V_5
IL_0028: beq.s IL_0064
IL_002a: ldloc.s V_4
IL_002c: isinst ""int""
IL_0031: brfalse.s IL_0062
IL_0033: br.s IL_0086
IL_0035: ldloc.s V_4
IL_0037: isinst ""int""
IL_003c: brfalse.s IL_0062
IL_003e: br.s IL_00a8
IL_0040: ldloc.s V_4
IL_0042: isinst ""byte""
IL_0047: brfalse.s IL_0062
IL_0049: ldloc.s V_4
IL_004b: unbox.any ""byte""
IL_0050: stloc.s V_6
IL_0052: br.s IL_0071
IL_0054: ldloc.s V_4
IL_0056: isinst ""byte""
IL_005b: brfalse.s IL_0062
IL_005d: ldc.i4.1
IL_005e: ldloc.s V_6
IL_0060: beq.s IL_009b
IL_0062: br.s IL_00b6
IL_0064: ldstr ""int 1""
IL_0069: call ""void System.Console.WriteLine(string)""
IL_006e: nop
IL_006f: br.s IL_00c4
IL_0071: ldloc.s V_6
IL_0073: stloc.0
IL_0074: call ""bool C.P()""
IL_0079: brtrue.s IL_007d
IL_007b: br.s IL_00
40
IL_007d: ldloc.
3
IL_007b: br.s IL_00
54
IL_007d: ldloc.
0
IL_007e: call ""void System.Console.WriteLine(int)""
IL_0083: nop
IL_0084: br.s IL_00c
7
IL_0086: ldloc.
1
IL_008
7: stloc.s V_4
IL_0084: br.s IL_00c
4
IL_0086: ldloc.
s V_5
IL_008
8: stloc.1
IL_0089: call ""bool C.P()""
IL_008e: brtrue.s IL_0092
IL_0090: br.s IL_00
5d
IL_0092: ldloc.
s V_4
IL_009
4
: call ""void System.Console.WriteLine(int)""
IL_009
9
: nop
IL_009
a: br.s IL_00c7
IL_009
c
: ldstr ""byte 1""
IL_00a
1
: call ""void System.Console.WriteLine(string)""
IL_00a
6
: nop
IL_00a
7: br.s IL_00c7
IL_00a
9: ldloc.1
IL_00aa: stloc.
s V_5
IL_00a
c: br.s IL_00ae
IL_00a
e: ldloc.s V_5
IL_00
b0
: call ""void System.Console.WriteLine(int)""
IL_00b
5
: nop
IL_00b
6: br.s IL_00c7
IL_00b
8: ldloc.0
IL_00b
9: stloc.s V_6
IL_00b
b: br.s IL_00bd
IL_00b
d: ldloc.s V_6
IL_00b
f
: call ""void System.Console.WriteLine(object)""
IL_00c
4
: nop
IL_00c
5: br.s IL_00c7
IL_00c
7
: ret
IL_0090: br.s IL_00
35
IL_0092: ldloc.
1
IL_009
3
: call ""void System.Console.WriteLine(int)""
IL_009
8
: nop
IL_009
9: br.s IL_00c4
IL_009
b
: ldstr ""byte 1""
IL_00a
0
: call ""void System.Console.WriteLine(string)""
IL_00a
5
: nop
IL_00a
6: br.s IL_00c4
IL_00a
8: ldloc.s V_5
IL_00aa: stloc.
2
IL_00a
b: br.s IL_00ad
IL_00a
d: ldloc.2
IL_00
ae
: call ""void System.Console.WriteLine(int)""
IL_00b
3
: nop
IL_00b
4: br.s IL_00c4
IL_00b
6: ldloc.s V_4
IL_00b
8: stloc.3
IL_00b
9: br.s IL_00bb
IL_00b
b: ldloc.3
IL_00b
c
: call ""void System.Console.WriteLine(object)""
IL_00c
1
: nop
IL_00c
2: br.s IL_00c4
IL_00c
4
: ret
}"
);
var
methodData0
=
v0
.
TestData
.
GetMethodData
(
"C.M"
);
var
method0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.M"
);
...
...
@@ -2532,108 +2519,98 @@ .maxstack 2
diff1
.
VerifyIL
(
"C.M"
,
@"
{
// Code size
200 (0xc8
)
// Code size
197 (0xc5
)
.maxstack 2
.locals init (
object V_0,
int V_1,
byte V_2,
byte V_3, //b
int V_4, //i
int V_5, //j
object V_6, //o
.locals init (
byte V_0, //b
int V_1,
//i
int V_2, //j
object V_3, //o
[object] V_4,
[int] V_5,
[unchanged] V_6,
object V_7,
[object] V_8,
object V_9)
object V_8,
int V_9,
byte V_10)
IL_0000: nop
IL_0001: call ""object C.F()""
IL_0006: stloc.s V_7
IL_0008: ldloc.s V_7
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: brtrue.s IL_0010
IL_000e: br.s IL_0063
IL_0010: ldloc.0
IL_0011: dup
IL_0012: stloc.s V_9
IL_0014: isinst ""int""
IL_0019: brfalse.s IL_002b
IL_001b: ldloc.s V_9
IL_001d: unbox.any ""int""
IL_0022: stloc.1
IL_0023: ldloc.1
IL_0024: ldc.i4.1
IL_0025: beq.s IL_0029
IL_0027: br.s IL_002b
IL_0029: br.s IL_0065
IL_002b: ldloc.0
IL_002c: dup
IL_002d: stloc.s V_9
IL_002f: isinst ""byte""
IL_0034: brfalse.s IL_0048
IL_0036: ldloc.s V_9
IL_0038: unbox.any ""byte""
IL_003d: stloc.2
IL_003e: br.s IL_0072
IL_0040: ldloc.2
IL_0041: ldc.i4.1
IL_0042: beq.s IL_0046
IL_0044: br.s IL_0048
IL_0046: br.s IL_009c
IL_0048: ldloc.0
IL_0049: dup
IL_004a: stloc.s V_9
IL_004c: isinst ""int""
IL_0051: brfalse.s IL_005f
IL_0053: ldloc.s V_9
IL_0055: unbox.any ""int""
IL_005a: stloc.1
IL_005b: br.s IL_0086
IL_005d: br.s IL_00a9
IL_005f: ldloc.0
IL_0060: stloc.0
IL_0061: br.s IL_00b8
IL_0063: br.s IL_00c7
IL_0065: ldstr ""int 1""
IL_006a: call ""void System.Console.WriteLine(string)""
IL_006f: nop
IL_0070: br.s IL_00c7
IL_0072: ldloc.2
IL_0073: stloc.3
IL_000a: stloc.s V_8
IL_000c: ldloc.s V_8
IL_000e: brfalse IL_00c4
IL_0013: ldloc.s V_8
IL_0015: isinst ""int""
IL_001a: brfalse.s IL_0040
IL_001c: ldloc.s V_8
IL_001e: unbox.any ""int""
IL_0023: stloc.s V_9
IL_0025: ldc.i4.1
IL_0026: ldloc.s V_9
IL_0028: beq.s IL_0064
IL_002a: ldloc.s V_8
IL_002c: isinst ""int""
IL_0031: brfalse.s IL_0062
IL_0033: br.s IL_0086
IL_0035: ldloc.s V_8
IL_0037: isinst ""int""
IL_003c: brfalse.s IL_0062
IL_003e: br.s IL_00a8
IL_0040: ldloc.s V_8
IL_0042: isinst ""byte""
IL_0047: brfalse.s IL_0062
IL_0049: ldloc.s V_8
IL_004b: unbox.any ""byte""
IL_0050: stloc.s V_10
IL_0052: br.s IL_0071
IL_0054: ldloc.s V_8
IL_0056: isinst ""byte""
IL_005b: brfalse.s IL_0062
IL_005d: ldc.i4.1
IL_005e: ldloc.s V_10
IL_0060: beq.s IL_009b
IL_0062: br.s IL_00b6
IL_0064: ldstr ""int 1""
IL_0069: call ""void System.Console.WriteLine(string)""
IL_006e: nop
IL_006f: br.s IL_00c4
IL_0071: ldloc.s V_10
IL_0073: stloc.0
IL_0074: call ""bool C.P()""
IL_0079: brtrue.s IL_007d
IL_007b: br.s IL_00
40
IL_007d: ldloc.
3
IL_007b: br.s IL_00
54
IL_007d: ldloc.
0
IL_007e: call ""void System.Console.WriteLine(int)""
IL_0083: nop
IL_0084: br.s IL_00c
7
IL_0086: ldloc.
1
IL_008
7: stloc.s V_4
IL_0084: br.s IL_00c
4
IL_0086: ldloc.
s V_9
IL_008
8: stloc.1
IL_0089: call ""bool C.P()""
IL_008e: brtrue.s IL_0092
IL_0090: br.s IL_00
5d
IL_0092: ldloc.
s V_4
IL_009
4
: call ""void System.Console.WriteLine(int)""
IL_009
9
: nop
IL_009
a: br.s IL_00c7
IL_009
c
: ldstr ""byte 1""
IL_00a
1
: call ""void System.Console.WriteLine(string)""
IL_00a
6
: nop
IL_00a
7: br.s IL_00c7
IL_00a
9: ldloc.1
IL_00aa: stloc.
s V_5
IL_00a
c: br.s IL_00ae
IL_00a
e: ldloc.s V_5
IL_00
b0
: call ""void System.Console.WriteLine(int)""
IL_00b
5
: nop
IL_00b
6: br.s IL_00c7
IL_00b
8: ldloc.0
IL_00b
9: stloc.s V_6
IL_00b
b: br.s IL_00bd
IL_00b
d: ldloc.s V_6
IL_00b
f
: call ""void System.Console.WriteLine(object)""
IL_00c
4
: nop
IL_00c
5: br.s IL_00c7
IL_00c
7
: ret
IL_0090: br.s IL_00
35
IL_0092: ldloc.
1
IL_009
3
: call ""void System.Console.WriteLine(int)""
IL_009
8
: nop
IL_009
9: br.s IL_00c4
IL_009
b
: ldstr ""byte 1""
IL_00a
0
: call ""void System.Console.WriteLine(string)""
IL_00a
5
: nop
IL_00a
6: br.s IL_00c4
IL_00a
8: ldloc.s V_9
IL_00aa: stloc.
2
IL_00a
b: br.s IL_00ad
IL_00a
d: ldloc.2
IL_00
ae
: call ""void System.Console.WriteLine(int)""
IL_00b
3
: nop
IL_00b
4: br.s IL_00c4
IL_00b
6: ldloc.s V_8
IL_00b
8: stloc.3
IL_00b
9: br.s IL_00bb
IL_00b
b: ldloc.3
IL_00b
c
: call ""void System.Console.WriteLine(object)""
IL_00c
1
: nop
IL_00c
2: br.s IL_00c4
IL_00c
4
: ret
}"
);
}
...
...
@@ -3606,7 +3583,7 @@ .maxstack 2
"
,
methodToken
:
diff1
.
UpdatedMethods
.
Single
());
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): code quality"
)
]
[
Fact
]
public
void
PatternVariable
()
{
var
source
=
@"
...
...
@@ -3632,21 +3609,21 @@ class C
diff1
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 42 (0x2a)
.maxstack
2
.maxstack
1
.locals init (int V_0, //i
bool V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
objec
t V_4,
in
t V_4,
int V_5)
-IL_0000: nop
-IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.s V_4
IL_000
5: isinst ""int""
IL_000a:
brfalse.s IL_0017
IL_000
c: ld
loc.s V_4
IL_00
0e: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_0017
IL_000
9: ldarg.0
IL_000a:
unbox.any ""int""
IL_000
f: st
loc.s V_4
IL_00
11: ldloc.s V_4
IL_0013: stloc.0
IL_0014: ldc.i4.1
IL_0015: br.s IL_0018
...
...
@@ -3773,7 +3750,7 @@ .maxstack 2
"
,
methodToken
:
diff1
.
UpdatedMethods
.
Single
());
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): code quality"
)
]
[
Fact
]
public
void
PatternMatching_Variable
()
{
var
source
=
@"
...
...
@@ -3799,21 +3776,21 @@ class C
diff1
.
VerifyIL
(
"C.F"
,
@"
{
// Code size 42 (0x2a)
.maxstack
2
.maxstack
1
.locals init (int V_0, //i
bool V_1,
[
objec
t] V_2,
[
in
t] V_2,
[int] V_3,
objec
t V_4,
in
t V_4,
int V_5)
-IL_0000: nop
-IL_0001: ldarg.0
IL_0002:
dup
IL_000
3: stloc.s V_4
IL_000
5: isinst ""int""
IL_000a:
brfalse.s IL_0017
IL_000
c: ld
loc.s V_4
IL_00
0e: unbox.any ""int""
IL_0002:
isinst ""int""
IL_000
7: brfalse.s IL_0017
IL_000
9: ldarg.0
IL_000a:
unbox.any ""int""
IL_000
f: st
loc.s V_4
IL_00
11: ldloc.s V_4
IL_0013: stloc.0
IL_0014: ldc.i4.1
IL_0015: br.s IL_0018
...
...
@@ -3833,7 +3810,7 @@ .maxstack 2
}"
,
methodToken
:
diff1
.
UpdatedMethods
.
Single
());
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): code quality"
)
]
[
Fact
]
public
void
PatternMatching_NoVariable
()
{
var
source
=
@"
...
...
@@ -3858,33 +3835,42 @@ class C
diff1
.
VerifyIL
(
"C.F"
,
@"
{
// Code size
39 (0x27
)
// Code size
52 (0x34
)
.maxstack 2
.locals init (bool V_0,
[int] V_1,
int V_2)
[int] V_2,
int V_3,
int V_4)
-IL_0000: nop
-IL_0001: ldarg.0
IL_0002: isinst ""bool""
IL_0007: brtrue.s IL_0017
IL_0009: ldc.i4.0
IL_000a: box ""int""
IL_000f: ldarg.0
IL_0010: call ""bool object.Equals(object, object)""
IL_0015: br.s IL_0018
IL_0017: ldc.i4.1
IL_0018: stloc.0
~IL_0019: ldloc.0
IL_001a: brfalse.s IL_0021
-IL_001c: nop
-IL_001d: ldc.i4.0
IL_001e: stloc.2
IL_001f: br.s IL_0025
-IL_0021: ldc.i4.1
IL_0022: stloc.2
IL_0023: br.s IL_0025
-IL_0025: ldloc.2
IL_0026: ret
IL_0007: brtrue.s IL_0021
IL_0009: ldarg.0
IL_000a: isinst ""int""
IL_000f: brfalse.s IL_001e
IL_0011: ldarg.0
IL_0012: unbox.any ""int""
IL_0017: stloc.3
IL_0018: ldloc.3
IL_0019: ldc.i4.0
IL_001a: ceq
IL_001c: br.s IL_001f
IL_001e: ldc.i4.0
IL_001f: br.s IL_0022
IL_0021: ldc.i4.1
IL_0022: stloc.0
~IL_0023: ldloc.0
IL_0024: brfalse.s IL_002c
-IL_0026: nop
-IL_0027: ldc.i4.0
IL_0028: stloc.s V_4
IL_002a: br.s IL_0031
-IL_002c: ldc.i4.1
IL_002d: stloc.s V_4
IL_002f: br.s IL_0031
-IL_0031: ldloc.s V_4
IL_0033: ret
}
"
,
methodToken
:
diff1
.
UpdatedMethods
.
Single
());
}
...
...
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
浏览文件 @
d1237c0d
...
...
@@ -3358,7 +3358,7 @@ .maxstack 1
}"
);
}
[
Fact
(
Skip
=
"PROTOTYPE(patterns2): This test is sensitive to the precise code generated, which is currently in flux."
)
]
[
Fact
]
[
WorkItem
(
19734
,
"https://github.com/dotnet/roslyn/issues/19734"
)]
public
void
SwitchWithConstantGenericPattern_01
()
{
...
...
@@ -3408,125 +3408,99 @@ static void M2<T>()
c
.
VerifyDiagnostics
();
var
verifier
=
CompileAndVerify
(
c
,
expectedOutput
:
"1234"
);
// PROTOTYPE(patterns2): Need to restore code quality
verifier
.
VerifyIL
(
qualifiedMethodName
:
"Program.M1<T>"
,
sequencePoints
:
"Program.M1"
,
source
:
source
,
expectedIL
:
@"{
// Code size 80 (0x50)
.maxstack 2
.locals init (T V_0,
int V_1,
T V_2, //t
int V_3, //i
int V_4,
object V_5,
T V_6)
// Code size 67 (0x43)
.maxstack 1
.locals init (T V_0, //t
int V_1, //i
int V_2,
T V_3,
int V_4)
// sequence point: {
IL_0000: nop
// sequence point: switch (1)
IL_0001: ldc.i4.1
IL_0002: stloc.s V_4
IL_0004: ldc.i4.1
IL_0005: box ""int""
IL_000a: stloc.s V_5
IL_000c: ldloc.s V_5
IL_000e: isinst ""T""
IL_0013: ldnull
IL_0014: cgt.un
IL_0016: dup
IL_0017: brtrue.s IL_0025
IL_0019: ldloca.s V_6
IL_001b: initobj ""T""
IL_0021: ldloc.s V_6
IL_0023: br.s IL_002c
IL_0025: ldloc.s V_5
IL_0027: unbox.any ""T""
IL_002c: stloc.0
IL_002d: brfalse.s IL_0031
IL_002f: br.s IL_0035
IL_0031: ldc.i4.1
IL_0032: stloc.1
IL_0005: stloc.2
IL_0006: ldloc.2
IL_0007: box ""int""
IL_000c: isinst ""T""
IL_0011: brfalse.s IL_0026
IL_0013: ldloc.2
IL_0014: box ""int""
IL_0019: isinst ""T""
IL_001e: unbox.any ""T""
IL_0023: stloc.3
IL_0024: br.s IL_0028
IL_0026: br.s IL_0035
IL_0028: ldloc.3
IL_0029: stloc.0
IL_002a: br.s IL_002c
// sequence point: Console.Write(1);
IL_002c: ldc.i4.1
IL_002d: call ""void System.Console.Write(int)""
IL_0032: nop
// sequence point: break;
IL_0033: br.s IL_0042
// sequence point: <hidden>
IL_0035: ldloc.0
IL_0036: stloc.2
IL_0035: ldloc.2
IL_0036: stloc.1
IL_0037: br.s IL_0039
// sequence point: Console.Write(
1
);
IL_0039: ldc.i4.
1
// sequence point: Console.Write(
2
);
IL_0039: ldc.i4.
2
IL_003a: call ""void System.Console.Write(int)""
IL_003f: nop
// sequence point: break;
IL_0040: br.s IL_004f
// sequence point: <hidden>
IL_0042: ldloc.1
IL_0043: stloc.3
IL_0044: br.s IL_0046
// sequence point: Console.Write(2);
IL_0046: ldc.i4.2
IL_0047: call ""void System.Console.Write(int)""
IL_004c: nop
// sequence point: break;
IL_004d: br.s IL_004f
IL_0040: br.s IL_0042
// sequence point: }
IL_004
f
: ret
IL_004
2
: ret
}"
);
verifier
.
VerifyIL
(
qualifiedMethodName
:
"Program.M2<T>"
,
sequencePoints
:
"Program.M2"
,
source
:
source
,
expectedIL
:
@"{
// Code size 87 (0x57)
.maxstack 2
.locals init (T V_0,
string V_1,
T V_2, //t
string V_3, //s
string V_4,
object V_5,
T V_6)
// Code size 65 (0x41)
.maxstack 1
.locals init (T V_0, //t
string V_1, //s
string V_2,
T V_3,
string V_4)
// sequence point: {
IL_0000: nop
// sequence point: switch (nameof(M2))
IL_0001: ldstr ""M2""
IL_0006: stloc.s V_4
IL_0008: ldstr ""M2""
IL_000d: stloc.s V_5
IL_000f: ldloc.s V_5
IL_0011: isinst ""T""
IL_0016: ldnull
IL_0017: cgt.un
IL_0019: dup
IL_001a: brtrue.s IL_0028
IL_001c: ldloca.s V_6
IL_001e: initobj ""T""
IL_0024: ldloc.s V_6
IL_0026: br.s IL_002f
IL_0028: ldloc.s V_5
IL_002a: unbox.any ""T""
IL_002f: stloc.0
IL_0030: brfalse.s IL_0034
IL_0032: br.s IL_003c
IL_0034: ldstr ""M2""
IL_0039: stloc.1
IL_003a: br.s IL_0049
// sequence point: <hidden>
IL_003c: ldloc.0
IL_003d: stloc.2
IL_003e: br.s IL_0040
IL_000d: stloc.2
IL_000e: ldloc.2
IL_000f: isinst ""T""
IL_0014: brfalse.s IL_0024
IL_0016: ldloc.2
IL_0017: isinst ""T""
IL_001c: unbox.any ""T""
IL_0021: stloc.3
IL_0022: br.s IL_0026
IL_0024: br.s IL_0033
IL_0026: ldloc.3
IL_0027: stloc.0
IL_0028: br.s IL_002a
// sequence point: Console.Write(3);
IL_00
40
: ldc.i4.3
IL_00
41
: call ""void System.Console.Write(int)""
IL_00
46
: nop
IL_00
2a
: ldc.i4.3
IL_00
2b
: call ""void System.Console.Write(int)""
IL_00
30
: nop
// sequence point: break;
IL_0047: br.s IL_0056
// sequence point: <hidden>
IL_0049: ldloc.1
IL_004a: stloc.3
IL_004b: br.s IL_004d
IL_0031: br.s IL_0040
IL_0033: ldloc.2
IL_0034: stloc.1
IL_0035: br.s IL_0037
// sequence point: Console.Write(4);
IL_00
4d
: ldc.i4.4
IL_00
4e
: call ""void System.Console.Write(int)""
IL_00
53
: nop
IL_00
37
: ldc.i4.4
IL_00
38
: call ""void System.Console.Write(int)""
IL_00
3d
: nop
// sequence point: break;
IL_00
54: br.s IL_0056
IL_00
3e: br.s IL_0040
// sequence point: }
IL_00
56
: ret
IL_00
40
: ret
}"
);
// Check the release code generation too.
...
...
@@ -3536,72 +3510,49 @@ .maxstack 2
verifier
.
VerifyIL
(
"Program.M1<T>"
,
@"{
// Code size 57 (0x39)
.maxstack 2
.locals init (T V_0,
int V_1,
object V_2,
T V_3)
// Code size 46 (0x2e)
.maxstack 1
.locals init (int V_0,
T V_1)
IL_0000: ldc.i4.1
IL_0001:
box ""int""
IL_000
6: stloc.2
IL_000
7: ldloc.2
IL_0001:
stloc.0
IL_000
2: ldloc.0
IL_000
3: box ""int""
IL_0008: isinst ""T""
IL_000d: ldnull
IL_000e: cgt.un
IL_0010: dup
IL_0011: brtrue.s IL_001e
IL_0013: ldloca.s V_3
IL_0015: initobj ""T""
IL_001b: ldloc.3
IL_001c: br.s IL_0024
IL_001e: ldloc.2
IL_001f: unbox.any ""T""
IL_0024: stloc.0
IL_0025: brtrue.s IL_002b
IL_0027: ldc.i4.1
IL_0028: stloc.1
IL_0029: br.s IL_0032
IL_002b: ldc.i4.1
IL_002c: call ""void System.Console.Write(int)""
IL_0031: ret
IL_0032: ldc.i4.2
IL_0033: call ""void System.Console.Write(int)""
IL_0038: ret
IL_000d: brfalse.s IL_0027
IL_000f: ldloc.0
IL_0010: box ""int""
IL_0015: isinst ""T""
IL_001a: unbox.any ""T""
IL_001f: stloc.1
IL_0020: ldc.i4.1
IL_0021: call ""void System.Console.Write(int)""
IL_0026: ret
IL_0027: ldc.i4.2
IL_0028: call ""void System.Console.Write(int)""
IL_002d: ret
}"
);
verifier
.
VerifyIL
(
"Program.M2<T>"
,
@"{
// Code size 60 (0x3c)
.maxstack 2
.locals init (T V_0,
string V_1,
object V_2,
T V_3)
// Code size 40 (0x28)
.maxstack 1
.locals init (string V_0,
T V_1)
IL_0000: ldstr ""M2""
IL_0005: stloc.
2
IL_0006: ldloc.
2
IL_0005: stloc.
0
IL_0006: ldloc.
0
IL_0007: isinst ""T""
IL_000c: ldnull
IL_000d: cgt.un
IL_000f: dup
IL_0010: brtrue.s IL_001d
IL_0012: ldloca.s V_3
IL_0014: initobj ""T""
IL_001a: ldloc.3
IL_001b: br.s IL_0023
IL_001d: ldloc.2
IL_001e: unbox.any ""T""
IL_0023: stloc.0
IL_0024: brtrue.s IL_002e
IL_0026: ldstr ""M2""
IL_002b: stloc.1
IL_002c: br.s IL_0035
IL_002e: ldc.i4.3
IL_002f: call ""void System.Console.Write(int)""
IL_0034: ret
IL_0035: ldc.i4.4
IL_0036: call ""void System.Console.Write(int)""
IL_003b: ret
IL_000c: brfalse.s IL_0021
IL_000e: ldloc.0
IL_000f: isinst ""T""
IL_0014: unbox.any ""T""
IL_0019: stloc.1
IL_001a: ldc.i4.3
IL_001b: call ""void System.Console.Write(int)""
IL_0020: ret
IL_0021: ldc.i4.4
IL_0022: call ""void System.Console.Write(int)""
IL_0027: ret
}"
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录