Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
841044b0
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,发现更多精彩内容 >>
提交
841044b0
编写于
5月 10, 2017
作者:
N
Neal Gafter
提交者:
GitHub
5月 10, 2017
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Share pattern-matching temps when they are the same type. (#19378)
Fixes #19280
上级
2223e156
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
1092 addition
and
737 deletion
+1092
-737
src/Compilers/CSharp/Portable/Binder/PatternSwitchBinder.cs
src/Compilers/CSharp/Portable/Binder/PatternSwitchBinder.cs
+4
-6
src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
...rs/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
+5
-4
src/Compilers/CSharp/Portable/BoundTree/DecisionTree.cs
src/Compilers/CSharp/Portable/BoundTree/DecisionTree.cs
+0
-30
src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
...ompilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
+48
-2
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
...ing/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
+4
-15
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
+779
-390
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
+140
-152
src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs
...onEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs
+112
-138
未找到文件。
src/Compilers/CSharp/Portable/Binder/PatternSwitchBinder.cs
浏览文件 @
841044b0
...
...
@@ -64,7 +64,7 @@ internal override BoundStatement BindSwitchExpressionAndSections(SwitchStatement
BoundPatternSwitchLabel
defaultLabel
;
bool
isComplete
;
ImmutableArray
<
BoundPatternSwitchSection
>
switchSections
=
BindPatternSwitchSections
(
boundSwitchExpression
,
node
.
Sections
,
originalBinder
,
out
defaultLabel
,
out
isComplete
,
diagnostics
);
BindPatternSwitchSections
(
originalBinder
,
out
defaultLabel
,
out
isComplete
,
diagnostics
);
var
locals
=
GetDeclaredLocalsForScope
(
node
);
var
functions
=
GetDeclaredLocalFunctionsForScope
(
node
);
return
new
BoundPatternSwitchStatement
(
...
...
@@ -101,8 +101,6 @@ internal override void BindPatternSwitchLabelForInference(CasePatternSwitchLabel
/// the decision tree.
/// </summary>
private
ImmutableArray
<
BoundPatternSwitchSection
>
BindPatternSwitchSections
(
BoundExpression
boundSwitchExpression
,
SyntaxList
<
SwitchSectionSyntax
>
sections
,
Binder
originalBinder
,
out
BoundPatternSwitchLabel
defaultLabel
,
out
bool
isComplete
,
...
...
@@ -115,11 +113,11 @@ internal override void BindPatternSwitchLabelForInference(CasePatternSwitchLabel
// Bind match sections
var
boundPatternSwitchSectionsBuilder
=
ArrayBuilder
<
BoundPatternSwitchSection
>.
GetInstance
();
SubsumptionDiagnosticBuilder
subsumption
=
new
SubsumptionDiagnosticBuilder
(
ContainingMemberOrLambda
,
this
.
Conversions
,
boundSwitch
Expression
);
foreach
(
var
sectionSyntax
in
s
ections
)
SubsumptionDiagnosticBuilder
subsumption
=
new
SubsumptionDiagnosticBuilder
(
ContainingMemberOrLambda
,
SwitchSyntax
,
this
.
Conversions
,
SwitchGoverning
Expression
);
foreach
(
var
sectionSyntax
in
SwitchSyntax
.
S
ections
)
{
boundPatternSwitchSectionsBuilder
.
Add
(
BindPatternSwitchSection
(
boundSwitch
Expression
,
sectionSyntax
,
originalBinder
,
ref
defaultLabel
,
ref
someValueMatched
,
subsumption
,
diagnostics
));
SwitchGoverning
Expression
,
sectionSyntax
,
originalBinder
,
ref
defaultLabel
,
ref
someValueMatched
,
subsumption
,
diagnostics
));
}
isComplete
=
defaultLabel
!=
null
||
subsumption
.
IsComplete
||
someValueMatched
;
...
...
src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
浏览文件 @
841044b0
...
...
@@ -20,11 +20,12 @@ internal class SubsumptionDiagnosticBuilder : DecisionTreeBuilder
private
readonly
DecisionTree
_subsumptionTree
;
internal
SubsumptionDiagnosticBuilder
(
Symbol
enclosingSymbol
,
Conversions
conversions
,
BoundExpression
expression
)
:
base
(
enclosingSymbol
,
conversions
)
SyntaxNode
syntax
,
Conversions
conversions
,
BoundExpression
expression
)
:
base
(
enclosingSymbol
,
syntax
,
conversions
)
{
_subsumptionTree
=
DecisionTree
.
Create
(
expression
,
expression
.
Type
,
enclosingSymbol
);
_subsumptionTree
=
CreateEmptyDecisionTree
(
expression
);
}
/// <summary>
...
...
src/Compilers/CSharp/Portable/BoundTree/DecisionTree.cs
浏览文件 @
841044b0
...
...
@@ -78,36 +78,6 @@ public DecisionTree(BoundExpression expression, TypeSymbol type, LocalSymbol tem
Debug
.
Assert
(
this
.
Type
!=
null
);
}
/// <summary>
/// Create a fresh decision tree for the given input expression of the given type.
/// </summary>
public
static
DecisionTree
Create
(
BoundExpression
expression
,
TypeSymbol
type
,
Symbol
enclosingSymbol
)
{
Debug
.
Assert
(
expression
.
Type
==
type
);
LocalSymbol
temp
=
null
;
if
(
expression
.
ConstantValue
==
null
)
{
// Unless it is a constant, the decision tree acts on a copy of the input expression.
// We create a temp to represent that copy. Lowering will assign into this temp.
temp
=
new
SynthesizedLocal
(
enclosingSymbol
as
MethodSymbol
,
type
,
SynthesizedLocalKind
.
PatternMatching
,
expression
.
Syntax
,
false
,
RefKind
.
None
);
expression
=
new
BoundLocal
(
expression
.
Syntax
,
temp
,
null
,
type
);
}
if
(
type
.
CanContainNull
()
||
type
.
SpecialType
==
SpecialType
.
None
)
{
// We need the ByType decision tree to separate null from non-null values.
// Note that, for the purpose of the decision tree (and subsumption), we
// ignore the fact that the input may be a constant, and therefore always
// or never null.
return
new
ByType
(
expression
,
type
,
temp
);
}
else
{
// If it is a (e.g. builtin) value type, we can switch on its (constant) values.
return
new
ByValue
(
expression
,
type
,
temp
);
}
}
/// <summary>
/// A decision tree node that branches based on (1) whether the input value is null, (2) the runtime
/// type of the input expression, and finally (3) a default decision tree if nothing in the previous
...
...
src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
浏览文件 @
841044b0
...
...
@@ -26,17 +26,63 @@ internal abstract class DecisionTreeBuilder
protected
readonly
Symbol
_enclosingSymbol
;
protected
readonly
Conversions
_conversions
;
protected
HashSet
<
DiagnosticInfo
>
_useSiteDiagnostics
=
new
HashSet
<
DiagnosticInfo
>();
private
Dictionary
<
TypeSymbol
,
LocalSymbol
>
localByType
=
new
Dictionary
<
TypeSymbol
,
LocalSymbol
>();
protected
DecisionTreeBuilder
(
Symbol
enclosingSymbol
,
SyntaxNode
syntax
,
Conversions
conversions
)
{
this
.
_enclosingSymbol
=
enclosingSymbol
;
this
.
Syntax
=
syntax
;
this
.
_conversions
=
conversions
;
}
protected
SyntaxNode
Syntax
{
private
get
;
set
;
}
private
LocalSymbol
PatternMatchingTemp
(
TypeSymbol
type
)
{
LocalSymbol
temp
;
if
(!
localByType
.
TryGetValue
(
type
,
out
temp
))
{
temp
=
new
SynthesizedLocal
(
_enclosingSymbol
as
MethodSymbol
,
type
,
SynthesizedLocalKind
.
PatternMatching
,
Syntax
);
localByType
.
Add
(
type
,
temp
);
}
return
temp
;
}
/// <summary>
/// Create a fresh decision tree for the given input expression of the given type.
/// </summary>
protected
DecisionTree
CreateEmptyDecisionTree
(
BoundExpression
expression
)
{
var
type
=
expression
.
Type
;
LocalSymbol
temp
=
null
;
if
(
expression
.
ConstantValue
==
null
)
{
// Unless it is a constant, the decision tree acts on a copy of the input expression.
// We create a temp to represent that copy. Lowering will assign into this temp.
temp
=
PatternMatchingTemp
(
type
);
expression
=
new
BoundLocal
(
expression
.
Syntax
,
temp
,
null
,
type
);
}
if
(
type
.
CanContainNull
()
||
type
.
SpecialType
==
SpecialType
.
None
)
{
// We need the ByType decision tree to separate null from non-null values.
// Note that, for the purpose of the decision tree (and subsumption), we
// ignore the fact that the input may be a constant, and therefore always
// or never null.
return
new
DecisionTree
.
ByType
(
expression
,
type
,
temp
);
}
else
{
// If it is a (e.g. builtin) value type, we can switch on its (constant) values.
return
new
DecisionTree
.
ByValue
(
expression
,
type
,
temp
);
}
}
protected
DecisionTree
AddToDecisionTree
(
DecisionTree
decisionTree
,
SyntaxNode
sectionSyntax
,
BoundPatternSwitchLabel
label
)
{
var
pattern
=
label
.
Pattern
;
...
...
@@ -237,7 +283,7 @@ private DecisionTree AddByValue(DecisionTree.ByType byType, BoundConstantPattern
if
(
forType
==
null
)
{
var
type
=
value
.
Value
.
Type
;
var
localSymbol
=
new
SynthesizedLocal
(
_enclosingSymbol
as
MethodSymbol
,
type
,
SynthesizedLocalKind
.
PatternMatching
,
Syntax
,
false
,
RefKind
.
Non
e
);
var
localSymbol
=
PatternMatchingTemp
(
typ
e
);
var
narrowedExpression
=
new
BoundLocal
(
Syntax
,
localSymbol
,
null
,
type
);
forType
=
new
DecisionTree
.
ByValue
(
narrowedExpression
,
value
.
Value
.
Type
.
TupleUnderlyingTypeOrSelf
(),
localSymbol
);
byType
.
TypeAndDecision
.
Add
(
new
KeyValuePair
<
TypeSymbol
,
DecisionTree
>(
value
.
Value
.
Type
,
forType
));
...
...
@@ -338,7 +384,7 @@ private DecisionTree AddByType(DecisionTree.ByType byType, TypeSymbol type, Deci
if
(
result
==
null
)
{
var
localSymbol
=
new
SynthesizedLocal
(
_enclosingSymbol
as
MethodSymbol
,
type
,
SynthesizedLocalKind
.
PatternMatching
,
Syntax
,
false
,
RefKind
.
Non
e
);
var
localSymbol
=
PatternMatchingTemp
(
typ
e
);
var
expression
=
new
BoundLocal
(
Syntax
,
localSymbol
,
null
,
type
);
result
=
makeDecision
(
expression
,
type
);
Debug
.
Assert
(
result
.
Temp
==
null
);
...
...
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
浏览文件 @
841044b0
...
...
@@ -38,7 +38,7 @@ private class PatternSwitchLocalRewriter : DecisionTreeBuilder
private
ArrayBuilder
<
BoundStatement
>
_loweredDecisionTree
=
ArrayBuilder
<
BoundStatement
>.
GetInstance
();
private
PatternSwitchLocalRewriter
(
LocalRewriter
localRewriter
,
BoundPatternSwitchStatement
node
)
:
base
(
localRewriter
.
_factory
.
CurrentMethod
,
localRewriter
.
_factory
.
Compilation
.
Conversions
)
:
base
(
localRewriter
.
_factory
.
CurrentMethod
,
node
.
Syntax
,
localRewriter
.
_factory
.
Compilation
.
Conversions
)
{
this
.
_localRewriter
=
localRewriter
;
this
.
_factory
=
localRewriter
.
_factory
;
...
...
@@ -59,15 +59,9 @@ private BoundStatement MakeLoweredForm(BoundPatternSwitchStatement node)
var
expression
=
_localRewriter
.
VisitExpression
(
node
.
Expression
);
var
result
=
ArrayBuilder
<
BoundStatement
>.
GetInstance
();
// if the expression is "too complex", we copy it to a temp.
LocalSymbol
initialTemp
=
null
;
if
(
expression
.
ConstantValue
==
null
)
{
initialTemp
=
_factory
.
SynthesizedLocal
(
expression
.
Type
,
expression
.
Syntax
);
result
.
Add
(
_factory
.
Assignment
(
_factory
.
Local
(
initialTemp
),
expression
));
expression
=
_factory
.
Local
(
initialTemp
);
// EnC: We need to insert a hidden sequence point to handle function remapping in case
// EnC: We need to insert a hidden sequence point to handle function remapping in case
// the containing method is edited while methods invoked in the expression are being executed.
if
(!
node
.
WasCompilerGenerated
&&
_localRewriter
.
Instrument
)
{
...
...
@@ -85,7 +79,6 @@ private BoundStatement MakeLoweredForm(BoundPatternSwitchStatement node)
}
// at this point the end of result is unreachable.
_declaredTemps
.
AddOptional
(
initialTemp
);
_declaredTemps
.
AddRange
(
node
.
InnerLocals
);
// output the sections of code
...
...
@@ -148,7 +141,7 @@ private void LowerPatternSwitch(BoundExpression loweredExpression, BoundPatternS
BoundExpression
loweredExpression
,
BoundPatternSwitchStatement
node
)
{
var
loweredDecisionTree
=
DecisionTree
.
Create
(
loweredExpression
,
loweredExpression
.
Type
,
_enclosingSymbol
);
var
loweredDecisionTree
=
CreateEmptyDecisionTree
(
loweredExpression
);
BoundPatternSwitchLabel
defaultLabel
=
null
;
SyntaxNode
defaultSection
=
null
;
foreach
(
var
section
in
node
.
SwitchSections
)
...
...
@@ -223,15 +216,11 @@ private void LowerDecisionTree(BoundExpression expression, DecisionTree decision
_loweredDecisionTree
.
Add
(
_factory
.
Assignment
(
decisionTree
.
Expression
,
convertedExpression
));
}
// If the temp is not yet in the declared temp set, add it now
if
(
_declaredTempSet
.
Add
(
decisionTree
.
Temp
))
{
_declaredTemps
.
Add
(
decisionTree
.
Temp
);
}
else
{
// we should only attempt to declare each temp once.
throw
ExceptionUtilities
.
Unreachable
;
}
}
switch
(
decisionTree
.
Kind
)
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
浏览文件 @
841044b0
此差异已折叠。
点击以展开。
src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
浏览文件 @
841044b0
...
...
@@ -2850,7 +2850,6 @@ class Student : Person { public double GPA; }
<slot kind=""35"" offset=""11"" />
<slot kind=""35"" offset=""46"" />
<slot kind=""35"" offset=""237"" />
<slot kind=""temp"" />
<slot kind=""0"" offset=""59"" />
<slot kind=""0"" offset=""163"" />
<slot kind=""0"" offset=""250"" />
...
...
@@ -2861,32 +2860,31 @@ class Student : Person { public double GPA; }
<sequencePoints>
<entry offset=""0x0"" startLine=""19"" startColumn=""5"" endLine=""19"" endColumn=""6"" />
<entry offset=""0x1"" startLine=""20"" startColumn=""9"" endLine=""20"" endColumn=""19"" />
<entry offset=""0x
6
"" hidden=""true"" />
<entry offset=""0x2
a
"" hidden=""true"" />
<entry offset=""0x2
d
"" startLine=""22"" startColumn=""28"" endLine=""22"" endColumn=""44"" />
<entry offset=""0x
41
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""57"" />
<entry offset=""0x
62
"" hidden=""true"" />
<entry offset=""0x6
7
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""57"" />
<entry offset=""0x8
8
"" hidden=""true"" />
<entry offset=""0x8
d
"" startLine=""27"" startColumn=""17"" endLine=""27"" endColumn=""59"" />
<entry offset=""0xa
9
"" startLine=""29"" startColumn=""17"" endLine=""29"" endColumn=""43"" />
<entry offset=""0xb
d
"" startLine=""31"" startColumn=""5"" endLine=""31"" endColumn=""6"" />
<entry offset=""0x
4
"" hidden=""true"" />
<entry offset=""0x2
8
"" hidden=""true"" />
<entry offset=""0x2
a
"" startLine=""22"" startColumn=""28"" endLine=""22"" endColumn=""44"" />
<entry offset=""0x
3d
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""57"" />
<entry offset=""0x
5c
"" hidden=""true"" />
<entry offset=""0x6
1
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""57"" />
<entry offset=""0x8
2
"" hidden=""true"" />
<entry offset=""0x8
7
"" startLine=""27"" startColumn=""17"" endLine=""27"" endColumn=""59"" />
<entry offset=""0xa
3
"" startLine=""29"" startColumn=""17"" endLine=""29"" endColumn=""43"" />
<entry offset=""0xb
7
"" startLine=""31"" startColumn=""5"" endLine=""31"" endColumn=""6"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0x
c0
"">
<scope startOffset=""0x2
a"" endOffset=""0x62
"">
<local name=""s"" il_index=""
4"" il_start=""0x2a"" il_end=""0x62
"" attributes=""0"" />
<scope startOffset=""0x0"" endOffset=""0x
ba
"">
<scope startOffset=""0x2
8"" endOffset=""0x5c
"">
<local name=""s"" il_index=""
3"" il_start=""0x28"" il_end=""0x5c
"" attributes=""0"" />
</scope>
<scope startOffset=""0x
62"" endOffset=""0x88
"">
<local name=""s"" il_index=""
5"" il_start=""0x62"" il_end=""0x88
"" attributes=""0"" />
<scope startOffset=""0x
5c"" endOffset=""0x82
"">
<local name=""s"" il_index=""
4"" il_start=""0x5c"" il_end=""0x82
"" attributes=""0"" />
</scope>
<scope startOffset=""0x8
8"" endOffset=""0xa9
"">
<local name=""t"" il_index=""
6"" il_start=""0x88"" il_end=""0xa9
"" attributes=""0"" />
<scope startOffset=""0x8
2"" endOffset=""0xa3
"">
<local name=""t"" il_index=""
5"" il_start=""0x82"" il_end=""0xa3
"" attributes=""0"" />
</scope>
</scope>
</method>
</methods>
</symbols>"
);
</symbols>"
);
}
[
Fact
]
...
...
@@ -2943,7 +2941,6 @@ class Student : Person { public double GPA; }
<slot kind=""35"" offset=""11"" />
<slot kind=""35"" offset=""46"" />
<slot kind=""35"" offset=""249"" />
<slot kind=""temp"" />
<slot kind=""1"" offset=""11"" />
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
...
...
@@ -2961,27 +2958,26 @@ class Student : Person { public double GPA; }
<entry offset=""0x0"" hidden=""true"" />
<entry offset=""0xd"" startLine=""19"" startColumn=""5"" endLine=""19"" endColumn=""6"" />
<entry offset=""0xe"" hidden=""true"" />
<entry offset=""0x
20
"" hidden=""true"" />
<entry offset=""0x4
5
"" hidden=""true"" />
<entry offset=""0x4
c
"" startLine=""22"" startColumn=""28"" endLine=""22"" endColumn=""44"" />
<entry offset=""0x6
4
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""63"" />
<entry offset=""0x7
4
"" hidden=""true"" />
<entry offset=""0x7
d
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""63"" />
<entry offset=""0x8
d
"" hidden=""true"" />
<entry offset=""0x9
7
"" startLine=""27"" startColumn=""17"" endLine=""27"" endColumn=""65"" />
<entry offset=""0xa
7
"" startLine=""29"" startColumn=""17"" endLine=""29"" endColumn=""49"" />
<entry offset=""0xb
7
"" startLine=""31"" startColumn=""5"" endLine=""31"" endColumn=""6"" />
<entry offset=""0x
1c
"" hidden=""true"" />
<entry offset=""0x4
1
"" hidden=""true"" />
<entry offset=""0x4
8
"" startLine=""22"" startColumn=""28"" endLine=""22"" endColumn=""44"" />
<entry offset=""0x6
0
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""63"" />
<entry offset=""0x7
0
"" hidden=""true"" />
<entry offset=""0x7
9
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""63"" />
<entry offset=""0x8
9
"" hidden=""true"" />
<entry offset=""0x9
3
"" startLine=""27"" startColumn=""17"" endLine=""27"" endColumn=""65"" />
<entry offset=""0xa
3
"" startLine=""29"" startColumn=""17"" endLine=""29"" endColumn=""49"" />
<entry offset=""0xb
3
"" startLine=""31"" startColumn=""5"" endLine=""31"" endColumn=""6"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0xb
a
"">
<local name=""CS$<>8__locals0"" il_index=""0"" il_start=""0x0"" il_end=""0xb
a
"" attributes=""0"" />
<scope startOffset=""0xe"" endOffset=""0xb
7
"">
<local name=""CS$<>8__locals1"" il_index=""1"" il_start=""0xe"" il_end=""0xb
7
"" attributes=""0"" />
<scope startOffset=""0x0"" endOffset=""0xb
6
"">
<local name=""CS$<>8__locals0"" il_index=""0"" il_start=""0x0"" il_end=""0xb
6
"" attributes=""0"" />
<scope startOffset=""0xe"" endOffset=""0xb
3
"">
<local name=""CS$<>8__locals1"" il_index=""1"" il_start=""0xe"" il_end=""0xb
3
"" attributes=""0"" />
</scope>
</scope>
</method>
</methods>
</symbols>"
);
</symbols>"
);
}
#
endregion
...
...
@@ -6476,113 +6472,106 @@ static void M(object o)
var
c
=
CreateCompilationWithMscorlibAndSystemCore
(
source
,
options
:
TestOptions
.
DebugDll
);
CompileAndVerify
(
c
).
VerifyIL
(
"Program.M"
,
@"{
// Code size
202 (0xca
)
// Code size
194 (0xc2
)
.maxstack 2
.locals init (object V_0,
int V_1,
object V_2,
object
V_3,
int?
V_4,
objec
t V_5,
in
t V_6,
int?
V_3,
object
V_4,
in
t V_5,
objec
t V_6,
object V_7,
object V_8,
object V_9)
object V_8)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.2
IL_0003: ldloc.2
IL_0004: stloc.3
IL_0005: ldloc.3
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brtrue.s IL_000c
IL_000a: br.s IL_005a
IL_000c: ldloc.0
IL_000d: isinst ""int?""
IL_0012: unbox.any ""int?""
IL_0017: stloc.s V_4
IL_0019: ldloca.s V_4
IL_001b: call ""int int?.GetValueOrDefault()""
IL_0020: stloc.1
IL_0021: ldloca.s V_4
IL_0023: call ""bool int?.HasValue.get""
IL_0028: brfalse.s IL_005a
IL_002a: ldloc.1
IL_002b: ldc.i4.1
IL_002c: sub
IL_002d: switch (
IL_0048,
IL_0050,
IL_0056,
IL_004e,
IL_0054)
IL_0046: br.s IL_005a
IL_0048: br.s IL_005c
IL_004a: br.s IL_0068
IL_004c: br.s IL_0076
IL_004e: br.s IL_0066
IL_0050: br.s IL_0061
IL_0052: br.s IL_005a
IL_0054: br.s IL_0072
IL_0056: br.s IL_006d
IL_0058: br.s IL_005a
IL_005a: br.s IL_0074
IL_005c: ldarg.0
IL_005d: brfalse.s IL_0066
IL_005f: br.s IL_004a
IL_0061: ldarg.0
IL_0062: brfalse.s IL_0066
IL_0064: br.s IL_0052
IL_0066: br.s IL_0078
IL_0068: ldarg.0
IL_0069: brtrue.s IL_0072
IL_006b: br.s IL_004c
IL_006d: ldarg.0
IL_006e: brtrue.s IL_0072
IL_0070: br.s IL_0058
IL_0072: br.s IL_0078
IL_0074: br.s IL_0078
IL_0076: br.s IL_0078
IL_0078: ldarg.0
IL_0079: stloc.2
IL_007a: ldloc.2
IL_007b: stloc.s V_7
IL_007d: ldloc.s V_7
IL_007f: stloc.s V_5
IL_0081: ldloc.s V_5
IL_0083: brtrue.s IL_0087
IL_0085: br.s IL_00b0
IL_0087: ldloc.s V_5
IL_0089: isinst ""int?""
IL_008e: unbox.any ""int?""
IL_0093: stloc.s V_4
IL_0095: ldloca.s V_4
IL_0097: call ""int int?.GetValueOrDefault()""
IL_009c: stloc.s V_6
IL_009e: ldloca.s V_4
IL_00a0: call ""bool int?.HasValue.get""
IL_00a5: brfalse.s IL_00b0
IL_00a7: ldloc.s V_6
IL_00a9: ldc.i4.1
IL_00aa: beq.s IL_00ae
IL_0004: stloc.0
IL_0005: ldloc.0
IL_0006: brtrue.s IL_000a
IL_0008: br.s IL_0057
IL_000a: ldloc.0
IL_000b: isinst ""int?""
IL_0010: unbox.any ""int?""
IL_0015: stloc.3
IL_0016: ldloca.s V_3
IL_0018: call ""int int?.GetValueOrDefault()""
IL_001d: stloc.1
IL_001e: ldloca.s V_3
IL_0020: call ""bool int?.HasValue.get""
IL_0025: brfalse.s IL_0057
IL_0027: ldloc.1
IL_0028: ldc.i4.1
IL_0029: sub
IL_002a: switch (
IL_0045,
IL_004d,
IL_0053,
IL_004b,
IL_0051)
IL_0043: br.s IL_0057
IL_0045: br.s IL_0059
IL_0047: br.s IL_0065
IL_0049: br.s IL_0073
IL_004b: br.s IL_0063
IL_004d: br.s IL_005e
IL_004f: br.s IL_0057
IL_0051: br.s IL_006f
IL_0053: br.s IL_006a
IL_0055: br.s IL_0057
IL_0057: br.s IL_0071
IL_0059: ldarg.0
IL_005a: brfalse.s IL_0063
IL_005c: br.s IL_0047
IL_005e: ldarg.0
IL_005f: brfalse.s IL_0063
IL_0061: br.s IL_004f
IL_0063: br.s IL_0075
IL_0065: ldarg.0
IL_0066: brtrue.s IL_006f
IL_0068: br.s IL_0049
IL_006a: ldarg.0
IL_006b: brtrue.s IL_006f
IL_006d: br.s IL_0055
IL_006f: br.s IL_0075
IL_0071: br.s IL_0075
IL_0073: br.s IL_0075
IL_0075: ldarg.0
IL_0076: stloc.s V_6
IL_0078: ldloc.s V_6
IL_007a: stloc.s V_4
IL_007c: ldloc.s V_4
IL_007e: brtrue.s IL_0082
IL_0080: br.s IL_00aa
IL_0082: ldloc.s V_4
IL_0084: isinst ""int?""
IL_0089: unbox.any ""int?""
IL_008e: stloc.3
IL_008f: ldloca.s V_3
IL_0091: call ""int int?.GetValueOrDefault()""
IL_0096: stloc.s V_5
IL_0098: ldloca.s V_3
IL_009a: call ""bool int?.HasValue.get""
IL_009f: brfalse.s IL_00aa
IL_00a1: ldloc.s V_5
IL_00a3: ldc.i4.1
IL_00a4: beq.s IL_00a8
IL_00a6: br.s IL_00aa
IL_00a8: br.s IL_00ac
IL_00aa: br.s IL_00ae
IL_00ac: br.s IL_00b0
IL_00ae: br.s IL_00b2
IL_00b0: br.s IL_00b4
IL_00b2: br.s IL_00b6
IL_00b4: br.s IL_00b6
IL_00b6: ldarg.0
IL_00b7: stloc.2
IL_00b8: ldloc.2
IL_00b9: stloc.s V_9
IL_00bb: ldloc.s V_9
IL_00bd: stloc.s V_8
IL_00bf: ldloc.s V_8
IL_00c1: brtrue.s IL_00c5
IL_00c3: br.s IL_00c5
IL_00c5: br.s IL_00c7
IL_00c7: br.s IL_00c9
IL_00c9: ret
IL_00ae: br.s IL_00b0
IL_00b0: ldarg.0
IL_00b1: stloc.s V_8
IL_00b3: ldloc.s V_8
IL_00b5: stloc.s V_7
IL_00b7: ldloc.s V_7
IL_00b9: brtrue.s IL_00bd
IL_00bb: br.s IL_00bd
IL_00bd: br.s IL_00bf
IL_00bf: br.s IL_00c1
IL_00c1: ret
}"
);
c
.
VerifyPdb
(
@"<symbols>
...
...
@@ -6595,7 +6584,6 @@ .maxstack 2
<encLocalSlotMap>
<slot kind=""35"" offset=""11"" />
<slot kind=""35"" offset=""46"" />
<slot kind=""temp"" />
<slot kind=""1"" offset=""11"" />
<slot kind=""temp"" />
<slot kind=""35"" offset=""378"" />
...
...
@@ -6608,23 +6596,23 @@ .maxstack 2
<sequencePoints>
<entry offset=""0x0"" startLine=""4"" startColumn=""5"" endLine=""4"" endColumn=""6"" />
<entry offset=""0x1"" startLine=""5"" startColumn=""9"" endLine=""5"" endColumn=""19"" />
<entry offset=""0x
5
"" hidden=""true"" />
<entry offset=""0x5
c
"" startLine=""7"" startColumn=""20"" endLine=""7"" endColumn=""34"" />
<entry offset=""0x
61
"" startLine=""9"" startColumn=""20"" endLine=""9"" endColumn=""34"" />
<entry offset=""0x6
6
"" startLine=""10"" startColumn=""17"" endLine=""10"" endColumn=""23"" />
<entry offset=""0x6
8
"" startLine=""11"" startColumn=""20"" endLine=""11"" endColumn=""34"" />
<entry offset=""0x6
d
"" startLine=""13"" startColumn=""20"" endLine=""13"" endColumn=""34"" />
<entry offset=""0x
72
"" startLine=""14"" startColumn=""17"" endLine=""14"" endColumn=""23"" />
<entry offset=""0x7
4
"" startLine=""16"" startColumn=""17"" endLine=""16"" endColumn=""23"" />
<entry offset=""0x7
6
"" startLine=""18"" startColumn=""17"" endLine=""18"" endColumn=""23"" />
<entry offset=""0x7
8
"" startLine=""20"" startColumn=""9"" endLine=""20"" endColumn=""19"" />
<entry offset=""0x7
d
"" hidden=""true"" />
<entry offset=""0x
b2
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""23"" />
<entry offset=""0x
b4
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""23"" />
<entry offset=""0xb
6
"" startLine=""27"" startColumn=""9"" endLine=""27"" endColumn=""19"" />
<entry offset=""0xb
b
"" hidden=""true"" />
<entry offset=""0x
c7
"" startLine=""30"" startColumn=""17"" endLine=""30"" endColumn=""23"" />
<entry offset=""0xc
9
"" startLine=""32"" startColumn=""5"" endLine=""32"" endColumn=""6"" />
<entry offset=""0x
3
"" hidden=""true"" />
<entry offset=""0x5
9
"" startLine=""7"" startColumn=""20"" endLine=""7"" endColumn=""34"" />
<entry offset=""0x
5e
"" startLine=""9"" startColumn=""20"" endLine=""9"" endColumn=""34"" />
<entry offset=""0x6
3
"" startLine=""10"" startColumn=""17"" endLine=""10"" endColumn=""23"" />
<entry offset=""0x6
5
"" startLine=""11"" startColumn=""20"" endLine=""11"" endColumn=""34"" />
<entry offset=""0x6
a
"" startLine=""13"" startColumn=""20"" endLine=""13"" endColumn=""34"" />
<entry offset=""0x
6f
"" startLine=""14"" startColumn=""17"" endLine=""14"" endColumn=""23"" />
<entry offset=""0x7
1
"" startLine=""16"" startColumn=""17"" endLine=""16"" endColumn=""23"" />
<entry offset=""0x7
3
"" startLine=""18"" startColumn=""17"" endLine=""18"" endColumn=""23"" />
<entry offset=""0x7
5
"" startLine=""20"" startColumn=""9"" endLine=""20"" endColumn=""19"" />
<entry offset=""0x7
8
"" hidden=""true"" />
<entry offset=""0x
ac
"" startLine=""23"" startColumn=""17"" endLine=""23"" endColumn=""23"" />
<entry offset=""0x
ae
"" startLine=""25"" startColumn=""17"" endLine=""25"" endColumn=""23"" />
<entry offset=""0xb
0
"" startLine=""27"" startColumn=""9"" endLine=""27"" endColumn=""19"" />
<entry offset=""0xb
3
"" hidden=""true"" />
<entry offset=""0x
bf
"" startLine=""30"" startColumn=""17"" endLine=""30"" endColumn=""23"" />
<entry offset=""0xc
1
"" startLine=""32"" startColumn=""5"" endLine=""32"" endColumn=""6"" />
</sequencePoints>
</method>
</methods>
...
...
src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs
浏览文件 @
841044b0
...
...
@@ -167,12 +167,11 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5, //s
int V_6,
object V_7,
int? V_8)
string V_3, //a
string V_4, //s
int V_5,
object V_6,
int? V_7)
IL_0000: ldarg.0
IL_0001: ret
}"
);
...
...
@@ -183,32 +182,29 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5, //s
int V_6,
object V_7,
int? V_8)
string V_3, //a
string V_4, //s
int V_5,
object V_6,
int? V_7)
IL_0000: ldarg.1
IL_0001: ret
}"
);
VerifyLocal
(
testData
,
typeName
,
locals
[
2
],
"<>m2"
,
"a"
,
expectedILOpt
:
@"{
// Code size
3 (0x3
)
// Code size
2 (0x2
)
.maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5, //s
int V_6,
object V_7,
int? V_8)
IL_0000: ldloc.s V_4
IL_0002: ret
}
"
);
string V_3, //a
string V_4, //s
int V_5,
object V_6,
int? V_7)
IL_0000: ldloc.3
IL_0001: ret
}"
);
VerifyLocal
(
testData
,
typeName
,
locals
[
3
],
"<>m3"
,
"s"
,
expectedILOpt
:
@"{
// Code size 3 (0x3)
...
...
@@ -216,13 +212,12 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5, //s
int V_6,
object V_7,
int? V_8)
IL_0000: ldloc.s V_5
string V_3, //a
string V_4, //s
int V_5,
object V_6,
int? V_7)
IL_0000: ldloc.s V_4
IL_0002: ret
}"
);
locals
.
Free
();
...
...
@@ -243,12 +238,11 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5,
int V_6, //s
object V_7,
int? V_8)
string V_3, //a
string V_4,
int V_5, //s
object V_6,
int? V_7)
IL_0000: ldarg.0
IL_0001: ret
}"
);
...
...
@@ -259,32 +253,29 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5,
int V_6, //s
object V_7,
int? V_8)
string V_3, //a
string V_4,
int V_5, //s
object V_6,
int? V_7)
IL_0000: ldarg.1
IL_0001: ret
}"
);
VerifyLocal
(
testData
,
typeName
,
locals
[
2
],
"<>m2"
,
"a"
,
expectedILOpt
:
@"{
// Code size
3 (0x3
)
// Code size
2 (0x2
)
.maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5,
int V_6, //s
object V_7,
int? V_8)
IL_0000: ldloc.s V_4
IL_0002: ret
}
"
);
string V_3, //a
string V_4,
int V_5, //s
object V_6,
int? V_7)
IL_0000: ldloc.3
IL_0001: ret
}"
);
VerifyLocal
(
testData
,
typeName
,
locals
[
3
],
"<>m3"
,
"s"
,
expectedILOpt
:
@"{
// Code size 3 (0x3)
...
...
@@ -292,13 +283,12 @@ .maxstack 1
.locals init (object V_0,
string V_1,
int V_2,
object V_3,
string V_4, //a
string V_5,
int V_6, //s
object V_7,
int? V_8)
IL_0000: ldloc.s V_6
string V_3, //a
string V_4,
int V_5, //s
object V_6,
int? V_7)
IL_0000: ldloc.s V_5
IL_0002: ret
}"
);
locals
.
Free
();
...
...
@@ -358,9 +348,8 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldarg.0
IL_0001: ret
}"
);
...
...
@@ -373,9 +362,8 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldarg.1
IL_0001: ret
}"
);
...
...
@@ -388,14 +376,12 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}
"
);
}"
);
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
//@"{
...
...
@@ -435,9 +421,8 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldarg.0
IL_0001: ret
}"
);
...
...
@@ -450,9 +435,8 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldarg.1
IL_0001: ret
}"
);
...
...
@@ -465,14 +449,12 @@ .maxstack 1
string V_2,
int V_3,
object V_4,
object V_5,
int? V_6,
System.Action V_7)
int? V_5,
System.Action V_6)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}
"
);
}"
);
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
//@"{
...
...
@@ -607,13 +589,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<M>d__1.<>4__this""
IL_0006: ret
...
...
@@ -625,13 +606,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.o""
IL_0006: ret
...
...
@@ -643,13 +623,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<a>5__4""
IL_0006: ret
...
...
@@ -661,13 +640,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<s>5__5""
IL_0006: ret
...
...
@@ -690,13 +668,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<M>d__1.<>4__this""
IL_0006: ret
...
...
@@ -708,13 +685,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.o""
IL_0006: ret
...
...
@@ -726,13 +702,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<a>5__4""
IL_0006: ret
...
...
@@ -744,13 +719,12 @@ .maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
object V_3,
string V_4,
int? V_5,
System.Runtime.CompilerServices.TaskAwaiter<object> V_6,
C.<M>d__1 V_7,
System.Runtime.CompilerServices.TaskAwaiter<object> V_8,
System.Exception V_9)
string V_3,
int? V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
C.<M>d__1 V_6,
System.Runtime.CompilerServices.TaskAwaiter<object> V_7,
System.Exception V_8)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__1.<s>5__6""
IL_0006: ret
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录