Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a98e5998
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,发现更多精彩内容 >>
提交
a98e5998
编写于
12月 28, 2016
作者:
V
Vladimir Sadov
提交者:
GitHub
12月 28, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #16054 from dotnet/degenerateSwitch
Better codegen quality when emitting degenerate switches.
上级
0f7bc6ee
609258f1
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
2211 addition
and
1427 deletion
+2211
-1427
src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
+12
-2
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs
...Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs
+328
-341
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
+40
-47
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
+1385
-725
src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.SwitchBucket.cs
...le/CodeGen/SwitchIntegralJumpTableEmitter.SwitchBucket.cs
+109
-15
src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs
...s/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs
+59
-21
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
...pilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
+87
-89
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb
...mpilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb
+151
-148
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenSelectCase.vb
...pilers/VisualBasic/Test/Emit/CodeGen/CodeGenSelectCase.vb
+40
-39
未找到文件。
src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
浏览文件 @
a98e5998
...
@@ -1075,11 +1075,15 @@ private void EmitSwitchStatement(BoundSwitchStatement switchStatement)
...
@@ -1075,11 +1075,15 @@ private void EmitSwitchStatement(BoundSwitchStatement switchStatement)
EmitSwitchBody
(
switchStatement
.
InnerLocals
,
switchSections
,
breakLabel
,
switchStatement
.
Syntax
);
EmitSwitchBody
(
switchStatement
.
InnerLocals
,
switchSections
,
breakLabel
,
switchStatement
.
Syntax
);
}
}
private
static
KeyValuePair
<
ConstantValue
,
object
>[]
GetSwitchCaseLabels
(
ImmutableArray
<
BoundSwitchSection
>
sections
,
ref
LabelSymbol
fallThroughLabel
)
private
KeyValuePair
<
ConstantValue
,
object
>[]
GetSwitchCaseLabels
(
ImmutableArray
<
BoundSwitchSection
>
sections
,
ref
LabelSymbol
fallThroughLabel
)
{
{
var
labelsBuilder
=
ArrayBuilder
<
KeyValuePair
<
ConstantValue
,
object
>>.
GetInstance
();
var
labelsBuilder
=
ArrayBuilder
<
KeyValuePair
<
ConstantValue
,
object
>>.
GetInstance
();
foreach
(
var
section
in
sections
)
foreach
(
var
section
in
sections
)
{
{
// all labels in a section are labeling the same region of code,
// so we could use just the first one for a better codegen
object
firstLabelInSection
=
null
;
foreach
(
BoundSwitchLabel
boundLabel
in
section
.
SwitchLabels
)
foreach
(
BoundSwitchLabel
boundLabel
in
section
.
SwitchLabels
)
{
{
var
label
=
boundLabel
.
Label
;
var
label
=
boundLabel
.
Label
;
...
@@ -1092,7 +1096,13 @@ private void EmitSwitchStatement(BoundSwitchStatement switchStatement)
...
@@ -1092,7 +1096,13 @@ private void EmitSwitchStatement(BoundSwitchStatement switchStatement)
var
value
=
boundLabel
.
ConstantValueOpt
;
var
value
=
boundLabel
.
ConstantValueOpt
;
Debug
.
Assert
(
value
!=
null
Debug
.
Assert
(
value
!=
null
&&
SwitchConstantValueHelper
.
IsValidSwitchCaseLabelConstant
(
value
));
&&
SwitchConstantValueHelper
.
IsValidSwitchCaseLabelConstant
(
value
));
labelsBuilder
.
Add
(
new
KeyValuePair
<
ConstantValue
,
object
>(
value
,
label
));
if
(
firstLabelInSection
==
null
)
{
firstLabelInSection
=
label
;
}
labelsBuilder
.
Add
(
new
KeyValuePair
<
ConstantValue
,
object
>(
value
,
firstLabelInSection
));
}
}
}
}
}
}
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs
浏览文件 @
a98e5998
此差异已折叠。
点击以展开。
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
浏览文件 @
a98e5998
...
@@ -441,7 +441,7 @@ .maxstack 2
...
@@ -441,7 +441,7 @@ .maxstack 2
"
);
"
);
compilation
.
VerifyIL
(
"Program.<Int0>d__0.System.IDisposable.Dispose()"
,
@"
compilation
.
VerifyIL
(
"Program.<Int0>d__0.System.IDisposable.Dispose()"
,
@"
{
{
// Code size
121 (0x79
)
// Code size
76 (0x4c
)
.maxstack 2
.maxstack 2
.locals init (int V_0)
.locals init (int V_0)
IL_0000: ldarg.0
IL_0000: ldarg.0
...
@@ -450,70 +450,63 @@ .locals init (int V_0)
...
@@ -450,70 +450,63 @@ .locals init (int V_0)
IL_0007: ldloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.s -5
IL_0008: ldc.i4.s -5
IL_000a: sub
IL_000a: sub
IL_000b: switch (
IL_000b: ldc.i4.2
IL_0041,
IL_000c: ble.un.s IL_0014
IL_0041,
IL_000e: ldloc.0
IL_0041,
IL_000f: ldc.i4.2
IL_0078,
IL_0010: sub
IL_0078,
IL_0011: ldc.i4.4
IL_0078,
IL_0012: bgt.un.s IL_004b
IL_0078,
IL_0014: nop
IL_0041,
IL_0041,
IL_0041,
IL_0041,
IL_0041)
IL_0040: ret
IL_0041: nop
.try
.try
{
{
IL_00
42
: ldloc.0
IL_00
15
: ldloc.0
IL_00
43
: ldc.i4.s -4
IL_00
16
: ldc.i4.s -4
IL_00
45: bgt.s IL_0053
IL_00
18: bgt.s IL_0026
IL_00
47
: ldloc.0
IL_00
1a
: ldloc.0
IL_00
48
: ldc.i4.s -5
IL_00
1b
: ldc.i4.s -5
IL_00
4a: beq.s IL_0067
IL_00
1d: beq.s IL_003a
IL_00
4c
: ldloc.0
IL_00
1f
: ldloc.0
IL_00
4d
: ldc.i4.s -4
IL_00
20
: ldc.i4.s -4
IL_00
4f: beq.s IL_005d
IL_00
22: beq.s IL_0030
IL_00
51: leave.s IL_0078
IL_00
24: leave.s IL_004b
IL_00
53
: ldloc.0
IL_00
26
: ldloc.0
IL_00
54
: ldc.i4.3
IL_00
27
: ldc.i4.3
IL_00
55: beq.s IL_005d
IL_00
28: beq.s IL_0030
IL_00
57
: ldloc.0
IL_00
2a
: ldloc.0
IL_00
58
: ldc.i4.5
IL_00
2b
: ldc.i4.5
IL_00
59: beq.s IL_0067
IL_00
2c: beq.s IL_003a
IL_00
5b: leave.s IL_0078
IL_00
2e: leave.s IL_004b
IL_00
5d
: nop
IL_00
30
: nop
.try
.try
{
{
IL_00
5e: leave.s IL_0078
IL_00
31: leave.s IL_004b
}
}
finally
finally
{
{
IL_00
60
: ldarg.0
IL_00
33
: ldarg.0
IL_00
61
: call ""void Program.<Int0>d__0.<>m__Finally2()""
IL_00
34
: call ""void Program.<Int0>d__0.<>m__Finally2()""
IL_00
66
: endfinally
IL_00
39
: endfinally
}
}
IL_00
67
: nop
IL_00
3a
: nop
.try
.try
{
{
IL_00
68: leave.s IL_0078
IL_00
3b: leave.s IL_004b
}
}
finally
finally
{
{
IL_00
6a
: ldarg.0
IL_00
3d
: ldarg.0
IL_00
6b
: call ""void Program.<Int0>d__0.<>m__Finally3()""
IL_00
3e
: call ""void Program.<Int0>d__0.<>m__Finally3()""
IL_00
70
: endfinally
IL_00
43
: endfinally
}
}
}
}
finally
finally
{
{
IL_00
71
: ldarg.0
IL_00
44
: ldarg.0
IL_00
72
: call ""void Program.<Int0>d__0.<>m__Finally1()""
IL_00
45
: call ""void Program.<Int0>d__0.<>m__Finally1()""
IL_00
77
: endfinally
IL_00
4a
: endfinally
}
}
IL_00
78
: ret
IL_00
4b
: ret
}
}
"
);
"
);
}
}
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
浏览文件 @
a98e5998
此差异已折叠。
点击以展开。
src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.SwitchBucket.cs
浏览文件 @
a98e5998
...
@@ -12,18 +12,49 @@ internal partial struct SwitchIntegralJumpTableEmitter
...
@@ -12,18 +12,49 @@ internal partial struct SwitchIntegralJumpTableEmitter
{
{
private
struct
SwitchBucket
private
struct
SwitchBucket
{
{
// sorted case labels
private
readonly
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
_allLabels
;
// range of sorted case labels within this bucket
// range of sorted case labels within this bucket
private
readonly
int
_startLabelIndex
;
private
readonly
int
_startLabelIndex
;
private
readonly
int
_endLabelIndex
;
private
readonly
int
_endLabelIndex
;
// sorted case labels
private
readonly
bool
_isKnownDegenerate
;
private
readonly
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
_allLabels
;
/// <summary>
/// Degenerate buckets here are buckets with contiguous range of constants
/// leading to the same label. Like:
///
/// case 0:
/// case 1:
/// case 2:
/// case 3:
/// DoOneThing();
/// break;
///
/// case 4:
/// case 5:
/// case 6:
/// case 7:
/// DoAnotherThing();
/// break;
///
/// NOTE: A trivial bucket with only one case constant is by definition degenerate.
/// </summary>
internal
bool
IsDegenerate
{
get
{
return
_isKnownDegenerate
;
}
}
internal
SwitchBucket
(
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
allLabels
,
int
index
)
internal
SwitchBucket
(
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
allLabels
,
int
index
)
{
{
_startLabelIndex
=
index
;
_startLabelIndex
=
index
;
_endLabelIndex
=
index
;
_endLabelIndex
=
index
;
_allLabels
=
allLabels
;
_allLabels
=
allLabels
;
_isKnownDegenerate
=
true
;
}
}
private
SwitchBucket
(
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
allLabels
,
int
startIndex
,
int
endIndex
)
private
SwitchBucket
(
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
allLabels
,
int
startIndex
,
int
endIndex
)
...
@@ -33,6 +64,18 @@ private SwitchBucket(ImmutableArray<KeyValuePair<ConstantValue, object>> allLabe
...
@@ -33,6 +64,18 @@ private SwitchBucket(ImmutableArray<KeyValuePair<ConstantValue, object>> allLabe
_startLabelIndex
=
startIndex
;
_startLabelIndex
=
startIndex
;
_endLabelIndex
=
endIndex
;
_endLabelIndex
=
endIndex
;
_allLabels
=
allLabels
;
_allLabels
=
allLabels
;
_isKnownDegenerate
=
false
;
}
internal
SwitchBucket
(
ImmutableArray
<
KeyValuePair
<
ConstantValue
,
object
>>
allLabels
,
int
startIndex
,
int
endIndex
,
bool
isDegenerate
)
{
Debug
.
Assert
((
uint
)
startIndex
<=
(
uint
)
endIndex
);
Debug
.
Assert
((
uint
)
startIndex
!=
(
uint
)
endIndex
||
isDegenerate
);
_startLabelIndex
=
startIndex
;
_endLabelIndex
=
endIndex
;
_allLabels
=
allLabels
;
_isKnownDegenerate
=
isDegenerate
;
}
}
internal
uint
LabelsCount
internal
uint
LabelsCount
...
@@ -60,26 +103,77 @@ internal ulong BucketSize
...
@@ -60,26 +103,77 @@ internal ulong BucketSize
}
}
}
}
// Relative cost of the bucket
// if a bucket could be split into two degenerate ones
// roughly proportional to the number of compares it needs in the success case.
// specifies a label index where the second bucket would start
internal
int
BucketCost
// -1 indicates that the bucket cannot be split into degenerate ones
// 0 indicates that the bucket is already degenerate
//
// Code Review question: why are we supporting splitting only in two buckets. Why not in more?
// Explanation:
// The input here is a "dense" bucket - the one that previous heuristics
// determined as not worth splitting.
//
// A dense bucket has rough execution cost of 1 conditional branch (range check)
// and 1 computed branch (which cost roughly the same as conditional one or perhaps more).
// The only way to surely beat that cost via splitting is if the bucket can be
// split into 2 degenerate buckets. Then we have just 2 conditional branches.
//
// 3 degenerate buckets would require up to 3 conditional branches.
// On some hardware computed jumps may cost significantly more than
// conditional ones (because they are harder to predict or whatever),
// so it could still be profitable, but I did not want to guess that.
//
// Basically if we have 3 degenerate buckets that can be merged into a dense bucket,
// we prefer a dense bucket, which we emit as "switch" opcode.
//
internal
int
DegenerateBucketSplit
{
{
get
get
{
{
if
(
_startLabelIndex
==
_endLabelIndex
)
if
(
IsDegenerate
)
{
return
0
;
}
Debug
.
Assert
(
_startLabelIndex
!=
_endLabelIndex
,
"1-sized buckets should be already known as degenerate."
);
var
allLabels
=
this
.
_allLabels
;
var
split
=
0
;
var
lastConst
=
this
.
StartConstant
;
var
lastLabel
=
allLabels
[
_startLabelIndex
].
Value
;
for
(
int
idx
=
_startLabelIndex
+
1
;
idx
<=
_endLabelIndex
;
idx
++)
{
{
// single element bucket needs exactly one compare
var
switchLabel
=
allLabels
[
idx
];
return
1
;
if
(
lastLabel
!=
switchLabel
.
Value
||
!
IsContiguous
(
lastConst
,
switchLabel
.
Key
))
{
if
(
split
!=
0
)
{
// found another discontinuity, so cannot be split
return
-
1
;
}
split
=
idx
;
lastLabel
=
switchLabel
.
Value
;
}
lastConst
=
switchLabel
.
Key
;
}
}
// dense switch will perform two branches (range check and the actual computed jump)
return
split
;
// computed jump is more expensive than a regular conditional branch
}
// based on benchmarks the combined cost seems to be closer to 3
}
//
// this also allows in the "mostly sparse" scenario to avoid numerous
private
bool
IsContiguous
(
ConstantValue
lastConst
,
ConstantValue
nextConst
)
// little switches with only 2 labels in them.
{
return
3
;
if
(!
lastConst
.
IsNumeric
||
!
nextConst
.
IsNumeric
)
{
return
false
;
}
}
return
GetBucketSize
(
lastConst
,
nextConst
)
==
2
;
}
}
private
static
ulong
GetBucketSize
(
ConstantValue
startConstant
,
ConstantValue
endConstant
)
private
static
ulong
GetBucketSize
(
ConstantValue
startConstant
,
ConstantValue
endConstant
)
...
...
src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs
浏览文件 @
a98e5998
...
@@ -217,22 +217,28 @@ private ImmutableArray<SwitchBucket> GenerateSwitchBuckets(int startLabelIndex,
...
@@ -217,22 +217,28 @@ private ImmutableArray<SwitchBucket> GenerateSwitchBuckets(int startLabelIndex,
Debug
.
Assert
(!
switchBucketsStack
.
IsEmpty
());
Debug
.
Assert
(!
switchBucketsStack
.
IsEmpty
());
// crumble leaf buckets
that are too small
// crumble leaf buckets
into degenerate buckets where possible
var
crumbled
=
ArrayBuilder
<
SwitchBucket
>.
GetInstance
();
var
crumbled
=
ArrayBuilder
<
SwitchBucket
>.
GetInstance
();
foreach
(
var
uncrumbled
in
switchBucketsStack
)
foreach
(
var
uncrumbled
in
switchBucketsStack
)
{
{
if
(
uncrumbled
.
BucketCost
>
uncrumbled
.
LabelsCount
)
var
degenerateSplit
=
uncrumbled
.
DegenerateBucketSplit
;
switch
(
degenerateSplit
)
{
{
// this bucket is no better than testing each label individually.
case
-
1
:
// we do not want to keep it.
// cannot be split
for
(
int
i
=
uncrumbled
.
StartLabelIndex
,
l
=
uncrumbled
.
EndLabelIndex
;
i
<=
l
;
i
++)
crumbled
.
Add
(
uncrumbled
);
{
break
;
crumbled
.
Add
(
new
SwitchBucket
(
_sortedCaseLabels
,
i
));
}
case
0
:
}
// already degenerate
else
crumbled
.
Add
(
new
SwitchBucket
(
_sortedCaseLabels
,
uncrumbled
.
StartLabelIndex
,
uncrumbled
.
EndLabelIndex
,
isDegenerate
:
true
));
{
break
;
crumbled
.
Add
(
uncrumbled
);
default
:
// can split
crumbled
.
Add
(
new
SwitchBucket
(
_sortedCaseLabels
,
uncrumbled
.
StartLabelIndex
,
degenerateSplit
-
1
,
isDegenerate
:
true
));
crumbled
.
Add
(
new
SwitchBucket
(
_sortedCaseLabels
,
degenerateSplit
,
uncrumbled
.
EndLabelIndex
,
isDegenerate
:
true
));
break
;
}
}
}
}
...
@@ -322,19 +328,25 @@ private void EmitSwitchBucket(SwitchBucket switchBucket, object bucketFallThroug
...
@@ -322,19 +328,25 @@ private void EmitSwitchBucket(SwitchBucket switchBucket, object bucketFallThroug
}
}
else
else
{
{
// Emit key normalized to startConstant (i.e. key - startConstant)
if
(
switchBucket
.
IsDegenerate
)
// switch (N, label1, label2... labelN)
{
// goto fallThroughLabel;
EmitRangeCheckedBranch
(
switchBucket
.
StartConstant
,
switchBucket
.
EndConstant
,
switchBucket
[
0
].
Value
);
}
this
.
EmitNormalizedSwitchKey
(
switchBucket
.
StartConstant
,
switchBucket
.
EndConstant
,
bucketFallThroughLabel
);
else
{
// Emit key normalized to startConstant (i.e. key - startConstant)
this
.
EmitNormalizedSwitchKey
(
switchBucket
.
StartConstant
,
switchBucket
.
EndConstant
,
bucketFallThroughLabel
);
// Create the labels array for emitting a switch instruction for the bucket
// Create the labels array for emitting a switch instruction for the bucket
object
[]
labels
=
this
.
CreateBucketLabels
(
switchBucket
);
object
[]
labels
=
this
.
CreateBucketLabels
(
switchBucket
);
// Emit the switch instruction
// switch (N, label1, label2... labelN)
_builder
.
EmitSwitch
(
labels
);
// Emit the switch instruction
_builder
.
EmitSwitch
(
labels
);
}
}
}
// goto fallThroughLabel;
_builder
.
EmitBranch
(
ILOpCode
.
Br
,
bucketFallThroughLabel
);
_builder
.
EmitBranch
(
ILOpCode
.
Br
,
bucketFallThroughLabel
);
}
}
...
@@ -434,6 +446,32 @@ private void EmitEqBranchForSwitch(ConstantValue constant, object targetLabel)
...
@@ -434,6 +446,32 @@ private void EmitEqBranchForSwitch(ConstantValue constant, object targetLabel)
}
}
}
}
private
void
EmitRangeCheckedBranch
(
ConstantValue
startConstant
,
ConstantValue
endConstant
,
object
targetLabel
)
{
_builder
.
EmitLoad
(
_key
);
// Normalize the key to 0 if needed
// Emit: ldc constant
// sub
if
(!
startConstant
.
IsDefaultValue
)
{
_builder
.
EmitConstantValue
(
startConstant
);
_builder
.
EmitOpCode
(
ILOpCode
.
Sub
);
}
if
(
_keyTypeCode
.
Is64BitIntegral
())
{
_builder
.
EmitLongConstant
(
endConstant
.
Int64Value
-
startConstant
.
Int64Value
);
}
else
{
_builder
.
EmitIntConstant
(
endConstant
.
Int32Value
-
startConstant
.
Int32Value
);
}
_builder
.
EmitBranch
(
ILOpCode
.
Ble_un
,
targetLabel
,
ILOpCode
.
Bgt_un
);
}
private
static
ILOpCode
GetReverseBranchCode
(
ILOpCode
branchCode
)
private
static
ILOpCode
GetReverseBranchCode
(
ILOpCode
branchCode
)
{
{
switch
(
branchCode
)
switch
(
branchCode
)
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
浏览文件 @
a98e5998
...
@@ -1625,7 +1625,7 @@ End Module
...
@@ -1625,7 +1625,7 @@ End Module
c
.
VerifyIL
(
"Form1.VB$StateMachine_1_f.MoveNext"
,
<
!
[
CDATA
[
c
.
VerifyIL
(
"Form1.VB$StateMachine_1_f.MoveNext"
,
<
!
[
CDATA
[
{
{
//
Code
size
23
6
(
0
xec
)
//
Code
size
23
3
(
0
xe9
)
.
maxstack
3
.
maxstack
3
.
locals
init
(
Integer
V_0
,
.
locals
init
(
Integer
V_0
,
Integer
V_1
,
Integer
V_1
,
...
@@ -1638,105 +1638,103 @@ End Module
...
@@ -1638,105 +1638,103 @@ End Module
.
try
.
try
{
{
IL_0007
:
ldloc
.
1
IL_0007
:
ldloc
.
1
IL_0008
:
brfalse
.
s
IL_000e
IL_0008
:
ldc
.
i4
.
1
IL_000a
:
ldloc
.
1
IL_0009
:
pop
IL_000b
:
ldc
.
i4
.
1
IL_000a
:
pop
IL_000c
:
pop
IL_000b
:
nop
IL_000d
:
pop
IL_000e
:
nop
.
try
.
try
{
{
IL_000c
:
ldloc
.
1
IL_000d
:
brfalse
.
s
IL_0065
IL_000f
:
ldloc
.
1
IL_000f
:
ldloc
.
1
IL_0010
:
brfalse
.
s
IL_0068
IL_0010
:
ldc
.
i4
.
1
IL_0012
:
ldloc
.
1
IL_0011
:
bne
.
un
.
s
IL_0021
IL_0013
:
ldc
.
i4
.
1
IL_0013
:
ldarg
.
0
IL_0014
:
bne
.
un
.
s
IL_0024
IL_0014
:
ldc
.
i4
.
m1
IL_0016
:
ldarg
.
0
IL_0015
:
dup
IL_0017
:
ldc
.
i4
.
m1
IL_0016
:
stloc
.
1
IL_0018
:
dup
IL_0017
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_0019
:
stloc
.
1
IL_001c
:
leave
IL_00e8
IL_001a
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_0021
:
ldstr
"2 "
IL_001f
:
leave
IL_00eb
IL_0026
:
call
"Sub System.Console.Write(String)"
IL_0024
:
ldstr
"2 "
IL_002b
:
call
"Function System.Threading.Tasks.Task.Yield() As System.Runtime.CompilerServices.YieldAwaitable"
IL_0029
:
call
"Sub System.Console.Write(String)"
IL_0030
:
stloc
.
3
IL_002e
:
call
"Function System.Threading.Tasks.Task.Yield() As System.Runtime.CompilerServices.YieldAwaitable"
IL_0031
:
ldloca
.
s
V_3
IL_0033
:
stloc
.
3
IL_0033
:
call
"Function System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter() As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0034
:
ldloca
.
s
V_3
IL_0038
:
stloc
.
2
IL_0036
:
call
"Function System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter() As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0039
:
ldloca
.
s
V_2
IL_003b
:
stloc
.
2
IL_003b
:
call
"Function System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.get_IsCompleted() As Boolean"
IL_003c
:
ldloca
.
s
V_2
IL_0040
:
brtrue
.
s
IL_0081
IL_003e
:
call
"Function System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.get_IsCompleted() As Boolean"
IL_0042
:
ldarg
.
0
IL_0043
:
brtrue
.
s
IL_0084
IL_0043
:
ldc
.
i4
.
0
IL_0045
:
ldarg
.
0
IL_0044
:
dup
IL_0046
:
ldc
.
i4
.
0
IL_0045
:
stloc
.
1
IL_0047
:
dup
IL_0046
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_0048
:
stloc
.
1
IL_004b
:
ldarg
.
0
IL_0049
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_004c
:
ldloc
.
2
IL_004e
:
ldarg
.
0
IL_004d
:
stfld
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_004f
:
ldloc
.
2
IL_0052
:
ldarg
.
0
IL_0050
:
stfld
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0053
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_0055
:
ldarg
.
0
IL_0058
:
ldloca
.
s
V_2
IL_0056
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_005a
:
ldarg
.
0
IL_005b
:
ldloca
.
s
V_2
IL_005b
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, Form1.VB$StateMachine_1_f)(ByRef System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ByRef Form1.VB$StateMachine_1_f)"
IL_005d
:
ldarg
.
0
IL_0060
:
leave
IL_00e8
IL_005e
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, Form1.VB$StateMachine_1_f)(ByRef System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ByRef Form1.VB$StateMachine_1_f)"
IL_0065
:
ldarg
.
0
IL_0063
:
leave
IL_00eb
IL_0066
:
ldc
.
i4
.
m1
IL_0068
:
ldarg
.
0
IL_0067
:
dup
IL_0069
:
ldc
.
i4
.
m1
IL_0068
:
stloc
.
1
IL_006a
:
dup
IL_0069
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_006b
:
stloc
.
1
IL_006e
:
ldarg
.
0
IL_006c
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_006f
:
ldfld
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0071
:
ldarg
.
0
IL_0074
:
stloc
.
2
IL_0072
:
ldfld
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0075
:
ldarg
.
0
IL_0077
:
stloc
.
2
IL_0076
:
ldflda
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0078
:
ldarg
.
0
IL_007b
:
initobj
"System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0079
:
ldflda
"Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0081
:
ldloca
.
s
V_2
IL_007e
:
initobj
"System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0083
:
call
"Sub System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()"
IL_0084
:
ldloca
.
s
V_2
IL_0088
:
ldloca
.
s
V_2
IL_0086
:
call
"Sub System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()"
IL_008a
:
initobj
"System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_008b
:
ldloca
.
s
V_2
IL_0090
:
ldstr
"3 "
IL_008d
:
initobj
"System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0095
:
call
"Sub System.Console.Write(String)"
IL_0093
:
ldstr
"3 "
IL_009a
:
ldc
.
i4
.
s
123
IL_0098
:
call
"Sub System.Console.Write(String)"
IL_009c
:
stloc
.
0
IL_009d
:
ldc
.
i4
.
s
123
IL_009d
:
leave
.
s
IL_00d2
IL_009f
:
stloc
.
0
IL_00a0
:
leave
.
s
IL_00d5
}
}
finally
finally
{
{
IL_00
a2
:
ldloc
.
1
IL_00
9f
:
ldloc
.
1
IL_00a
3
:
ldc
.
i4
.
0
IL_00a
0
:
ldc
.
i4
.
0
IL_00a
4
:
bge
.
s
IL_00b0
IL_00a
1
:
bge
.
s
IL_00ad
IL_00a
6
:
ldstr
"4 "
IL_00a
3
:
ldstr
"4 "
IL_00a
b
:
call
"Sub System.Console.Write(String)"
IL_00a
8
:
call
"Sub System.Console.Write(String)"
IL_00
b0
:
endfinally
IL_00
ad
:
endfinally
}
}
}
}
catch
System
.
Exception
catch
System
.
Exception
{
{
IL_00
b1
:
dup
IL_00
ae
:
dup
IL_00
b2
:
call
"Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
IL_00
af
:
call
"Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
IL_00b
7
:
stloc
.
s
V_4
IL_00b
4
:
stloc
.
s
V_4
IL_00b
9
:
ldarg
.
0
IL_00b
6
:
ldarg
.
0
IL_00b
a
:
ldc
.
i4
.
s
-
2
IL_00b
7
:
ldc
.
i4
.
s
-
2
IL_00b
c
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_00b
9
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_00
c1
:
ldarg
.
0
IL_00
be
:
ldarg
.
0
IL_00
c2
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00
bf
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00c
7
:
ldloc
.
s
V_4
IL_00c
4
:
ldloc
.
s
V_4
IL_00c
9
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetException(System.Exception)"
IL_00c
6
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetException(System.Exception)"
IL_00c
e
:
call
"Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
IL_00c
b
:
call
"Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
IL_00d
3
:
leave
.
s
IL_00eb
IL_00d
0
:
leave
.
s
IL_00e8
}
}
IL_00d
5
:
ldarg
.
0
IL_00d
2
:
ldarg
.
0
IL_00d
6
:
ldc
.
i4
.
s
-
2
IL_00d
3
:
ldc
.
i4
.
s
-
2
IL_00d
8
:
dup
IL_00d
5
:
dup
IL_00d
9
:
stloc
.
1
IL_00d
6
:
stloc
.
1
IL_00d
a
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_00d
7
:
stfld
"Form1.VB$StateMachine_1_f.$State As Integer"
IL_00d
f
:
ldarg
.
0
IL_00d
c
:
ldarg
.
0
IL_00
e0
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00
dd
:
ldflda
"Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00e
5
:
ldloc
.
0
IL_00e
2
:
ldloc
.
0
IL_00e
6
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetResult(Integer)"
IL_00e
3
:
call
"Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetResult(Integer)"
IL_00e
b
:
ret
IL_00e
8
:
ret
}
}
]]
>
)
]]
>
)
End
Sub
End
Sub
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb
浏览文件 @
a98e5998
...
@@ -628,7 +628,7 @@ End Module
...
@@ -628,7 +628,7 @@ End Module
CompileAndVerify
(
source
,
expectedOutput
:
=
"12345"
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.MoveNext"
,
<
!
[
CDATA
[
CompileAndVerify
(
source
,
expectedOutput
:
=
"12345"
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.MoveNext"
,
<
!
[
CDATA
[
{
{
//
Code
size
1
61
(
0
xa1
)
//
Code
size
1
52
(
0
x98
)
.
maxstack
3
.
maxstack
3
.
locals
init
(
Boolean
V_0
,
.
locals
init
(
Boolean
V_0
,
Integer
V_1
,
Integer
V_1
,
...
@@ -637,84 +637,85 @@ End Module
...
@@ -637,84 +637,85 @@ End Module
IL_0001
:
ldfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0001
:
ldfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0006
:
stloc
.
1
IL_0006
:
stloc
.
1
IL_0007
:
ldloc
.
1
IL_0007
:
ldloc
.
1
IL_0008
:
switch
(
IL_0008
:
brfalse
.
s
IL_0012
IL_001b
,
IL_000a
:
ldloc
.
1
IL_0024
,
IL_000b
:
ldc
.
i4
.
1
IL_0024
)
IL_000c
:
sub
IL_0019
:
ldc
.
i4
.
0
IL_000d
:
ldc
.
i4
.
1
IL_001a
:
ret
IL_000e
:
ble
.
un
.
s
IL_001b
IL_001b
:
ldarg
.
0
IL_0010
:
ldc
.
i4
.
0
IL_001c
:
ldc
.
i4
.
m1
IL_0011
:
ret
IL_001d
:
dup
IL_0012
:
ldarg
.
0
IL_001e
:
stloc
.
1
IL_0013
:
ldc
.
i4
.
m1
IL_001f
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0014
:
dup
IL_0024
:
nop
IL_0015
:
stloc
.
1
IL_0016
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_001b
:
nop
.
try
.
try
{
{
IL_0025
:
ldloc
.
1
IL_001c
:
ldloc
.
1
IL_0026
:
ldc
.
i4
.
1
IL_001d
:
ldc
.
i4
.
1
IL_0027
:
beq
.
s
IL_006d
IL_001e
:
beq
.
s
IL_0064
IL_0029
:
ldloc
.
1
IL_0020
:
ldloc
.
1
IL_002a
:
ldc
.
i4
.
2
IL_0021
:
ldc
.
i4
.
2
IL_002b
:
bne
.
un
.
s
IL_003a
IL_0022
:
bne
.
un
.
s
IL_0031
IL_002d
:
ldarg
.
0
IL_0024
:
ldarg
.
0
IL_002e
:
ldc
.
i4
.
m1
IL_0025
:
ldc
.
i4
.
m1
IL_002f
:
dup
IL_0026
:
dup
IL_0030
:
stloc
.
1
IL_0027
:
stloc
.
1
IL_0031
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0028
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0036
:
ldc
.
i4
.
1
IL_002d
:
ldc
.
i4
.
1
IL_0037
:
stloc
.
0
IL_002e
:
stloc
.
0
IL_0038
:
leave
.
s
IL_009f
IL_002f
:
leave
.
s
IL_0096
IL_003a
:
ldarg
.
0
IL_0031
:
ldarg
.
0
IL_003b
:
ldarg
.
0
IL_0032
:
ldarg
.
0
IL_003c
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$Local_x As System.Collections.Generic.IEnumerable(Of Integer)"
IL_0033
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$Local_x As System.Collections.Generic.IEnumerable(Of Integer)"
IL_0041
:
callvirt
"Function System.Collections.Generic.IEnumerable(Of Integer).GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0038
:
callvirt
"Function System.Collections.Generic.IEnumerable(Of Integer).GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0046
:
stfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_003d
:
stfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_004b
:
br
.
s
IL_0076
IL_0042
:
br
.
s
IL_006d
IL_004d
:
ldarg
.
0
IL_0044
:
ldarg
.
0
IL_004e
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0045
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0053
:
callvirt
"Function System.Collections.Generic.IEnumerator(Of Integer).get_Current() As Integer"
IL_004a
:
callvirt
"Function System.Collections.Generic.IEnumerator(Of Integer).get_Current() As Integer"
IL_0058
:
stloc
.
2
IL_004f
:
stloc
.
2
IL_0059
:
ldarg
.
0
IL_0050
:
ldarg
.
0
IL_005a
:
ldloc
.
2
IL_0051
:
ldloc
.
2
IL_005b
:
stfld
"Module1.VB$StateMachine_1_Foo.$Current As Integer"
IL_0052
:
stfld
"Module1.VB$StateMachine_1_Foo.$Current As Integer"
IL_0060
:
ldarg
.
0
IL_0057
:
ldarg
.
0
IL_0061
:
ldc
.
i4
.
1
IL_0058
:
ldc
.
i4
.
1
IL_0062
:
dup
IL_0059
:
dup
IL_0063
:
stloc
.
1
IL_005a
:
stloc
.
1
IL_0064
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_005b
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0069
:
ldc
.
i4
.
1
IL_0060
:
ldc
.
i4
.
1
IL_006a
:
stloc
.
0
IL_0061
:
stloc
.
0
IL_006b
:
leave
.
s
IL_009f
IL_0062
:
leave
.
s
IL_0096
IL_0064
:
ldarg
.
0
IL_0065
:
ldc
.
i4
.
m1
IL_0066
:
dup
IL_0067
:
stloc
.
1
IL_0068
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_006d
:
ldarg
.
0
IL_006d
:
ldarg
.
0
IL_006e
:
ldc
.
i4
.
m1
IL_006e
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_006f
:
dup
IL_0073
:
callvirt
"Function System.Collections.IEnumerator.MoveNext() As Boolean"
IL_0070
:
stloc
.
1
IL_0078
:
brtrue
.
s
IL_0044
IL_0071
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_007a
:
leave
.
s
IL_0094
IL_0076
:
ldarg
.
0
IL_0077
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_007c
:
callvirt
"Function System.Collections.IEnumerator.MoveNext() As Boolean"
IL_0081
:
brtrue
.
s
IL_004d
IL_0083
:
leave
.
s
IL_009d
}
}
finally
finally
{
{
IL_00
85
:
ldloc
.
1
IL_00
7c
:
ldloc
.
1
IL_00
86
:
ldc
.
i4
.
0
IL_00
7d
:
ldc
.
i4
.
0
IL_00
87
:
bge
.
s
IL_009c
IL_00
7e
:
bge
.
s
IL_0093
IL_008
9
:
ldarg
.
0
IL_008
0
:
ldarg
.
0
IL_008
a
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_008
1
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_008
f
:
brfalse
.
s
IL_009c
IL_008
6
:
brfalse
.
s
IL_0093
IL_00
91
:
ldarg
.
0
IL_00
88
:
ldarg
.
0
IL_00
92
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_00
89
:
ldfld
"Module1.VB$StateMachine_1_Foo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_00
97
:
callvirt
"Sub System.IDisposable.Dispose()"
IL_00
8e
:
callvirt
"Sub System.IDisposable.Dispose()"
IL_009
c
:
endfinally
IL_009
3
:
endfinally
}
}
IL_009d
:
ldc
.
i4
.
0
IL_0094
:
ldc
.
i4
.
0
IL_009e
:
ret
IL_0095
:
ret
IL_009f
:
ldloc
.
0
IL_0096
:
ldloc
.
0
IL_00a0
:
ret
IL_0097
:
ret
}
}
]]
>
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.IEnumerable.GetEnumerator"
,
<
!
[
CDATA
[
]]
>
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.IEnumerable.GetEnumerator"
,
<
!
[
CDATA
[
{
{
...
@@ -858,7 +859,7 @@ End Module
...
@@ -858,7 +859,7 @@ End Module
CompileAndVerify
(
source
,
expectedOutput
:
=
"233"
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.MoveNext"
,
<
!
[
CDATA
[
CompileAndVerify
(
source
,
expectedOutput
:
=
"233"
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.MoveNext"
,
<
!
[
CDATA
[
{
{
//
Code
size
1
68
(
0
xa8
)
//
Code
size
1
59
(
0
x9f
)
.
maxstack
3
.
maxstack
3
.
locals
init
(
Boolean
V_0
,
.
locals
init
(
Boolean
V_0
,
Integer
V_1
,
Integer
V_1
,
...
@@ -867,88 +868,90 @@ End Module
...
@@ -867,88 +868,90 @@ End Module
IL_0001
:
ldfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0001
:
ldfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0006
:
stloc
.
1
IL_0006
:
stloc
.
1
IL_0007
:
ldloc
.
1
IL_0007
:
ldloc
.
1
IL_0008
:
switch
(
IL_0008
:
brfalse
.
s
IL_0012
IL_001b
,
IL_000a
:
ldloc
.
1
IL_002b
,
IL_000b
:
ldc
.
i4
.
1
IL_002b
)
IL_000c
:
sub
IL_0019
:
ldc
.
i4
.
0
IL_000d
:
ldc
.
i4
.
1
IL_001a
:
ret
IL_000e
:
ble
.
un
.
s
IL_0022
IL_0010
:
ldc
.
i4
.
0
IL_0011
:
ret
IL_0012
:
ldarg
.
0
IL_0013
:
ldc
.
i4
.
m1
IL_0014
:
dup
IL_0015
:
stloc
.
1
IL_0016
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_001b
:
ldarg
.
0
IL_001b
:
ldarg
.
0
IL_001c
:
ldc
.
i4
.
m1
IL_001c
:
ldc
.
i4
.
1
IL_001d
:
dup
IL_001d
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_001e
:
stloc
.
1
IL_0022
:
nop
IL_001f
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_0024
:
ldarg
.
0
IL_0025
:
ldc
.
i4
.
1
IL_0026
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_002b
:
nop
.
try
.
try
{
{
IL_002
c
:
ldloc
.
1
IL_002
3
:
ldloc
.
1
IL_002
d
:
ldc
.
i4
.
1
IL_002
4
:
ldc
.
i4
.
1
IL_002
e
:
beq
.
s
IL_0068
IL_002
5
:
beq
.
s
IL_005f
IL_00
30
:
ldloc
.
1
IL_00
27
:
ldloc
.
1
IL_00
31
:
ldc
.
i4
.
2
IL_00
28
:
ldc
.
i4
.
2
IL_00
32
:
bne
.
un
.
s
IL_0041
IL_00
29
:
bne
.
un
.
s
IL_0038
IL_00
34
:
ldarg
.
0
IL_00
2b
:
ldarg
.
0
IL_00
35
:
ldc
.
i4
.
m1
IL_00
2c
:
ldc
.
i4
.
m1
IL_00
36
:
dup
IL_00
2d
:
dup
IL_00
37
:
stloc
.
1
IL_00
2e
:
stloc
.
1
IL_00
38
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_00
2f
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_003
d
:
ldc
.
i4
.
1
IL_003
4
:
ldc
.
i4
.
1
IL_003
e
:
stloc
.
0
IL_003
5
:
stloc
.
0
IL_003
f
:
leave
.
s
IL_00a6
IL_003
6
:
leave
.
s
IL_009d
IL_00
41
:
ldarg
.
0
IL_00
38
:
ldarg
.
0
IL_00
42
:
ldarg
.
0
IL_00
39
:
ldarg
.
0
IL_00
43
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
3a
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
48
:
ldc
.
i4
.
1
IL_00
3f
:
ldc
.
i4
.
1
IL_004
9
:
add
.
ovf
IL_004
0
:
add
.
ovf
IL_004
a
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_004
1
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_004
f
:
ldarg
.
0
IL_004
6
:
ldarg
.
0
IL_00
50
:
ldarg
.
0
IL_00
47
:
ldarg
.
0
IL_00
51
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
48
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
56
:
stfld
"Module1.VB$StateMachine_1_Foo.$Current As Integer"
IL_00
4d
:
stfld
"Module1.VB$StateMachine_1_Foo.$Current As Integer"
IL_005
b
:
ldarg
.
0
IL_005
2
:
ldarg
.
0
IL_005
c
:
ldc
.
i4
.
1
IL_005
3
:
ldc
.
i4
.
1
IL_005
d
:
dup
IL_005
4
:
dup
IL_005
e
:
stloc
.
1
IL_005
5
:
stloc
.
1
IL_005
f
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_005
6
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_00
64
:
ldc
.
i4
.
1
IL_00
5b
:
ldc
.
i4
.
1
IL_00
65
:
stloc
.
0
IL_00
5c
:
stloc
.
0
IL_00
66
:
leave
.
s
IL_00a6
IL_00
5d
:
leave
.
s
IL_009d
IL_00
68
:
ldarg
.
0
IL_00
5f
:
ldarg
.
0
IL_006
9
:
ldc
.
i4
.
m1
IL_006
0
:
ldc
.
i4
.
m1
IL_006
a
:
dup
IL_006
1
:
dup
IL_006
b
:
stloc
.
1
IL_006
2
:
stloc
.
1
IL_006
c
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_006
3
:
stfld
"Module1.VB$StateMachine_1_Foo.$State As Integer"
IL_00
71
:
leave
.
s
IL_00a4
IL_00
68
:
leave
.
s
IL_009b
}
}
finally
finally
{
{
IL_00
73
:
ldloc
.
1
IL_00
6a
:
ldloc
.
1
IL_00
74
:
ldc
.
i4
.
0
IL_00
6b
:
ldc
.
i4
.
0
IL_00
75
:
bge
.
s
IL_00a3
IL_00
6c
:
bge
.
s
IL_009a
IL_00
77
:
ldarg
.
0
IL_00
6e
:
ldarg
.
0
IL_00
78
:
ldarg
.
0
IL_00
6f
:
ldarg
.
0
IL_007
9
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_007
0
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_007
e
:
ldc
.
i4
.
1
IL_007
5
:
ldc
.
i4
.
1
IL_007
f
:
add
.
ovf
IL_007
6
:
add
.
ovf
IL_00
80
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
77
:
stfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
85
:
ldarg
.
0
IL_00
7c
:
ldarg
.
0
IL_00
86
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
7d
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_008
b
:
stloc
.
2
IL_008
2
:
stloc
.
2
IL_008
c
:
ldarg
.
0
IL_008
3
:
ldarg
.
0
IL_008
d
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_008
4
:
ldfld
"Module1.VB$StateMachine_1_Foo.$VB$ResumableLocal_x$0 As Integer"
IL_00
92
:
call
"Sub System.Console.Write(Integer)"
IL_00
89
:
call
"Sub System.Console.Write(Integer)"
IL_00
97
:
ldloca
.
s
V_2
IL_00
8e
:
ldloca
.
s
V_2
IL_009
9
:
call
"Function Integer.ToString() As String"
IL_009
0
:
call
"Function Integer.ToString() As String"
IL_009
e
:
call
"Sub System.Console.Write(String)"
IL_009
5
:
call
"Sub System.Console.Write(String)"
IL_00
a3
:
endfinally
IL_00
9a
:
endfinally
}
}
IL_00
a4
:
ldc
.
i4
.
0
IL_00
9b
:
ldc
.
i4
.
0
IL_00
a5
:
ret
IL_00
9c
:
ret
IL_00
a6
:
ldloc
.
0
IL_00
9d
:
ldloc
.
0
IL_00
a7
:
ret
IL_00
9e
:
ret
}
}
]]
>
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.IEnumerable.GetEnumerator"
,
<
!
[
CDATA
[
]]
>
).
VerifyIL
(
"Module1.VB$StateMachine_1_Foo.IEnumerable.GetEnumerator"
,
<
!
[
CDATA
[
{
{
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenSelectCase.vb
浏览文件 @
a98e5998
...
@@ -1411,22 +1411,20 @@ End Module
...
@@ -1411,22 +1411,20 @@ End Module
]]
></
file
>
]]
></
file
>
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
{
{
//
Code
size
31
(
0
x1f
)
//
Code
size
28
(
0
x1c
)
.
maxstack
2
.
maxstack
2
.
locals
init
(
Integer
V_0
)
.
locals
init
(
Integer
V_0
)
IL_0000
:
ldc
.
i4
.
0
IL_0000
:
ldc
.
i4
.
0
IL_0001
:
stloc
.
0
IL_0001
:
stloc
.
0
IL_0002
:
ldloc
.
0
IL_0002
:
ldloc
.
0
IL_0003
:
brfalse
.
s
IL_0009
IL_0003
:
ldc
.
i4
.
1
IL_0005
:
ldloc
.
0
IL_0004
:
bgt
.
un
.
s
IL_0011
IL_0006
:
ldc
.
i4
.
1
IL_0006
:
ldstr
"Success"
IL_0007
:
bne
.
un
.
s
IL_0014
IL_000b
:
call
"Sub System.Console.WriteLine(String)"
IL_0009
:
ldstr
"Success"
IL_0010
:
ret
IL_000e
:
call
"Sub System.Console.WriteLine(String)"
IL_0011
:
ldstr
"Fail"
IL_0013
:
ret
IL_0016
:
call
"Sub System.Console.WriteLine(String)"
IL_0014
:
ldstr
"Fail"
IL_001b
:
ret
IL_0019
:
call
"Sub System.Console.WriteLine(String)"
IL_001e
:
ret
}
}
]]
>
)
]]
>
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
...
@@ -1453,26 +1451,27 @@ End Module
...
@@ -1453,26 +1451,27 @@ End Module
]]
></
file
>
]]
></
file
>
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
{
{
//
Code
size
55
(
0
x37
)
//
Code
size
44
(
0
x2c
)
.
maxstack
1
.
maxstack
2
.
locals
init
(
Integer
V_0
)
.
locals
init
(
Integer
V_0
)
IL_0000
:
ldc
.
i4
.
0
IL_0000
:
ldc
.
i4
.
0
IL_0001
:
stloc
.
0
IL_0001
:
stloc
.
0
IL_0002
:
ldloc
.
0
IL_0002
:
ldloc
.
0
IL_0003
:
switch
(
IL_0003
:
brfalse
.
s
IL_0016
IL_0021
,
IL_0005
:
ldloc
.
0
IL_0016
,
IL_0006
:
ldc
.
i4
.
1
IL_0016
)
IL_0007
:
sub
IL_0014
:
br
.
s
IL_002c
IL_0008
:
ldc
.
i4
.
1
IL_0016
:
ldstr
"Fail"
IL_0009
:
bgt
.
un
.
s
IL_0021
IL_000b
:
ldstr
"Fail"
IL_0010
:
call
"Sub System.Console.WriteLine(String)"
IL_0015
:
ret
IL_0016
:
ldstr
"Success"
IL_001b
:
call
"Sub System.Console.WriteLine(String)"
IL_001b
:
call
"Sub System.Console.WriteLine(String)"
IL_0020
:
ret
IL_0020
:
ret
IL_0021
:
ldstr
"
Success
"
IL_0021
:
ldstr
"
Fail
"
IL_0026
:
call
"Sub System.Console.WriteLine(String)"
IL_0026
:
call
"Sub System.Console.WriteLine(String)"
IL_002b
:
ret
IL_002b
:
ret
IL_002c
:
ldstr
"Fail"
IL_0031
:
call
"Sub System.Console.WriteLine(String)"
IL_0036
:
ret
}
}
]]
>
)
]]
>
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
...
@@ -1499,7 +1498,7 @@ End Module
...
@@ -1499,7 +1498,7 @@ End Module
]]
></
file
>
]]
></
file
>
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
</
compilation
>
,
expectedOutput
:
=
"Success"
).
VerifyIL
(
"M1.Main"
,
<
!
[
CDATA
[
{
{
//
Code
size
61
(
0
x3d
)
//
Code
size
49
(
0
x31
)
.
maxstack
2
.
maxstack
2
.
locals
init
(
Integer
V_0
)
.
locals
init
(
Integer
V_0
)
IL_0000
:
ldc
.
i4
.
0
IL_0000
:
ldc
.
i4
.
0
...
@@ -1507,21 +1506,23 @@ End Module
...
@@ -1507,21 +1506,23 @@ End Module
IL_0002
:
ldloc
.
0
IL_0002
:
ldloc
.
0
IL_0003
:
ldc
.
i4
.
1
IL_0003
:
ldc
.
i4
.
1
IL_0004
:
sub
IL_0004
:
sub
IL_0005
:
switch
(
IL_0005
:
ldc
.
i4
.
1
IL_001c
,
IL_0006
:
ble
.
un
.
s
IL_0010
IL_001c
,
IL_0008
:
ldloc
.
0
IL_0027
,
IL_0009
:
ldc
.
i4
.
3
IL_0027
)
IL_000a
:
sub
IL_001a
:
br
.
s
IL_0032
IL_000b
:
ldc
.
i4
.
1
IL_001c
:
ldstr
"Fail"
IL_000c
:
ble
.
un
.
s
IL_001b
IL_0021
:
call
"Sub System.Console.WriteLine(String)"
IL_000e
:
br
.
s
IL_0026
IL_0026
:
ret
IL_0010
:
ldstr
"Fail"
IL_0027
:
ldstr
"Fail"
IL_0015
:
call
"Sub System.Console.WriteLine(String)"
IL_002c
:
call
"Sub System.Console.WriteLine(String)"
IL_001a
:
ret
IL_0031
:
ret
IL_001b
:
ldstr
"Fail"
IL_0032
:
ldstr
"Success"
IL_0020
:
call
"Sub System.Console.WriteLine(String)"
IL_0037
:
call
"Sub System.Console.WriteLine(String)"
IL_0025
:
ret
IL_003c
:
ret
IL_0026
:
ldstr
"Success"
IL_002b
:
call
"Sub System.Console.WriteLine(String)"
IL_0030
:
ret
}
}
]]
>
)
]]
>
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
VerifySynthesizedStringHashMethod
(
compVerifier
,
expected
:
=
False
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录