Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
bf8d2ec7
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,发现更多精彩内容 >>
提交
bf8d2ec7
编写于
11月 12, 2016
作者:
V
Vladimir Sadov
提交者:
GitHub
11月 12, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #14959 from VSadov/cacheThis
Introduce local caching of "this" in async methods
上级
c9a33590
8e5bf079
变更
19
展开全部
隐藏空白更改
内联
并排
Showing
19 changed file
with
1092 addition
and
491 deletion
+1092
-491
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
+32
-14
src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
...wering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
+7
-1
src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs
.../IteratorRewriter/IteratorMethodToStateMachineRewriter.cs
+12
-6
src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs
...rp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs
+1
-1
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs
...ring/StateMachineRewriter/MethodToStateMachineRewriter.cs
+54
-1
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineFieldSymbol.cs
.../Lowering/StateMachineRewriter/StateMachineFieldSymbol.cs
+8
-1
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
...ble/Lowering/StateMachineRewriter/StateMachineRewriter.cs
+2
-2
src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
...ers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
+7
-2
src/Compilers/CSharp/Test/Emit/BreakingChanges.cs
src/Compilers/CSharp/Test/Emit/BreakingChanges.cs
+96
-1
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs
...ilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs
+391
-1
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs
...ilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs
+1
-1
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs
...Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs
+284
-276
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
...p/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
+3
-3
src/Compilers/Core/Portable/SynthesizedLocalKind.cs
src/Compilers/Core/Portable/SynthesizedLocalKind.cs
+6
-0
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Await.vb
...ewriter/AsyncRewriter.AsyncMethodToClassRewriter.Await.vb
+1
-1
src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb
...ewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb
+1
-1
src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb
...ic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb
+1
-1
src/Compilers/VisualBasic/Portable/Lowering/SyntheticBoundNodeFactory.vb
...isualBasic/Portable/Lowering/SyntheticBoundNodeFactory.vb
+4
-0
src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs
...nEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs
+181
-178
未找到文件。
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
浏览文件 @
bf8d2ec7
...
...
@@ -871,17 +871,28 @@ private void EmitFieldLoad(BoundFieldAccess fieldAccess, bool used)
{
var
field
=
fieldAccess
.
FieldSymbol
;
//TODO: For static field access this may require ..ctor to run. Is this a side-effect?
// Accessing unused instance field on a struct is a noop. Just emit the receiver.
if
(!
used
&&
!
field
.
IsVolatile
&&
!
field
.
IsStatic
&&
fieldAccess
.
ReceiverOpt
.
Type
.
IsVerifierValue
())
if
(!
used
)
{
EmitExpression
(
fieldAccess
.
ReceiverOpt
,
used
:
false
);
return
;
// fetching unused captured frame is a no-op (like reading "this")
if
(
field
.
IsCapturedFrame
)
{
return
;
}
// Accessing a volatile field is sideeffecting because it establishes an acquire fence.
// Otherwise, accessing an unused instance field on a struct is a noop. Just emit an unused receiver.
if
(!
field
.
IsVolatile
&&
!
field
.
IsStatic
&&
fieldAccess
.
ReceiverOpt
.
Type
.
IsVerifierValue
())
{
EmitExpression
(
fieldAccess
.
ReceiverOpt
,
used
:
false
);
return
;
}
}
Debug
.
Assert
(!
field
.
IsConst
||
field
.
ContainingType
.
SpecialType
==
SpecialType
.
System_Decimal
,
"rewriter should lower constant fields into constant expressions"
);
// static field access is sideeffecting since it gurantees that ..ctor has run.
// we emit static accesses even if unused.
if
(
field
.
IsStatic
)
{
if
(
field
.
IsVolatile
)
...
...
@@ -1252,8 +1263,8 @@ private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver)
return
true
;
case
BoundKind
.
ObjectCreationExpression
:
//NOTE: there are cases involving ProxyAttribute
//where newobj may produce null
//
NOTE: there are cases involving ProxyAttribute
//
where newobj may produce null
return
true
;
case
BoundKind
.
Conversion
:
...
...
@@ -1262,8 +1273,8 @@ private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver)
switch
(
conversion
.
ConversionKind
)
{
case
ConversionKind
.
Boxing
:
//NOTE: boxing can produce null for Nullable, but any call through that
//will result in null reference exceptions anyways.
//
NOTE: boxing can produce null for Nullable, but any call through that
//
will result in null reference exceptions anyways.
return
true
;
case
ConversionKind
.
MethodGroup
:
...
...
@@ -1277,10 +1288,20 @@ private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver)
break
;
case
BoundKind
.
ThisReference
:
//NOTE: these actually can be null if called from a different language
//if that has already happen, we will just propagate the behavior.
// NOTE: these actually can be null if called from a different language
// however, we assume it is responsibility of the caller to nullcheck "this"
// if we already have access to "this", we must be in a member and should
// not redo the check
return
true
;
case
BoundKind
.
FieldAccess
:
// same reason as for "ThisReference"
return
((
BoundFieldAccess
)
receiver
).
FieldSymbol
.
IsCapturedFrame
;
case
BoundKind
.
Local
:
// same reason as for "ThisReference"
return
((
BoundLocal
)
receiver
).
LocalSymbol
.
SynthesizedKind
==
SynthesizedLocalKind
.
FrameCache
;
case
BoundKind
.
DelegateCreationExpression
:
return
true
;
...
...
@@ -1295,9 +1316,6 @@ private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver)
case
BoundKind
.
TypeOfOperator
:
return
true
;
case
BoundKind
.
FieldAccess
:
return
((
BoundFieldAccess
)
receiver
).
FieldSymbol
.
IsCapturedFrame
;
case
BoundKind
.
ConditionalReceiver
:
return
true
;
...
...
src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs
浏览文件 @
bf8d2ec7
...
...
@@ -125,6 +125,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod)
bodyBuilder
.
Add
(
F
.
HiddenSequencePoint
());
bodyBuilder
.
Add
(
F
.
Assignment
(
F
.
Local
(
cachedState
),
F
.
Field
(
F
.
This
(),
stateField
)));
bodyBuilder
.
Add
(
CacheThisIfNeeded
());
var
exceptionLocal
=
F
.
SynthesizedLocal
(
F
.
WellKnownType
(
WellKnownType
.
System_Exception
));
bodyBuilder
.
Add
(
...
...
@@ -194,6 +195,11 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod)
var
locals
=
ArrayBuilder
<
LocalSymbol
>.
GetInstance
();
locals
.
Add
(
cachedState
);
if
((
object
)
cachedThis
!=
null
)
{
locals
.
Add
(
cachedThis
);
}
if
((
object
)
_exprRetValue
!=
null
)
locals
.
Add
(
_exprRetValue
);
var
newBody
=
...
...
@@ -242,7 +248,7 @@ public override BoundNode VisitExpressionStatement(BoundExpressionStatement node
}
BoundExpression
expr
=
(
BoundExpression
)
this
.
Visit
(
node
.
Expression
);
return
(
expr
!=
null
)
?
node
.
Update
(
expr
)
:
(
BoundStatement
)
F
.
Block
();
return
(
expr
!=
null
)
?
node
.
Update
(
expr
)
:
(
BoundStatement
)
F
.
StatementList
();
}
public
override
BoundNode
VisitAwaitExpression
(
BoundAwaitExpression
node
)
...
...
src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs
浏览文件 @
bf8d2ec7
...
...
@@ -94,12 +94,15 @@ internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImpleme
// }
// state_0:
// state = -1;
// [optional: cachedThis = capturedThis;]
// [[rewritten body]]
newBody
=
F
.
Block
(
ImmutableArray
.
Create
(
cachedState
),
F
.
Block
(
F
.
HiddenSequencePoint
(),
F
.
Assignment
(
F
.
Local
(
cachedState
),
F
.
Field
(
F
.
This
(),
stateField
))
),
newBody
=
F
.
Block
((
object
)
cachedThis
==
null
?
ImmutableArray
.
Create
(
cachedState
):
ImmutableArray
.
Create
(
cachedState
,
cachedThis
),
F
.
HiddenSequencePoint
(),
F
.
Assignment
(
F
.
Local
(
cachedState
),
F
.
Field
(
F
.
This
(),
stateField
)),
CacheThisIfNeeded
(),
Dispatch
(),
GenerateReturn
(
finished
:
true
),
F
.
Label
(
initialLabel
),
...
...
@@ -386,8 +389,11 @@ public override BoundNode VisitTryStatement(BoundTryStatement node)
// return;
// }
Debug
.
Assert
(
frame
.
parent
.
finalizeState
==
_currentFinallyFrame
.
finalizeState
);
rewrittenHandler
=
F
.
Block
(
rewrittenHandler
=
F
.
Block
((
object
)
this
.
cachedThis
!=
null
?
ImmutableArray
.
Create
(
this
.
cachedThis
):
ImmutableArray
<
LocalSymbol
>.
Empty
,
F
.
Assignment
(
F
.
Field
(
F
.
This
(),
stateField
),
F
.
Literal
(
frame
.
parent
.
finalizeState
)),
CacheThisIfNeeded
(),
rewrittenHandler
,
F
.
Return
()
);
...
...
src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs
浏览文件 @
bf8d2ec7
...
...
@@ -310,7 +310,7 @@ private void GenerateEnumerableImplementation(ref BoundExpression managedThreadI
F
.
Assignment
(
F
.
Local
(
resultVariable
),
F
.
This
()),
// result = this;
method
.
IsStatic
||
method
.
ThisParameter
.
Type
.
IsReferenceType
?
// if this is a reference type, no need to copy it since it is not assignable
F
.
Goto
(
thisInitialized
)
:
// goto thisInitialized
(
BoundStatement
)
F
.
Block
()),
(
BoundStatement
)
F
.
StatementList
()),
elseClauseOpt
:
makeIterator
// else result = new IteratorClass(0)
);
...
...
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs
浏览文件 @
bf8d2ec7
...
...
@@ -44,6 +44,20 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter
/// </summary>
protected
readonly
LocalSymbol
cachedState
;
/// <summary>
/// Cached "this" local, used to store the captured "this", which is safe to cache locally since "this"
/// is sematically immutable.
/// It would be hard for such caching to happen at JIT level (since JIT does not know that it never changes).
/// NOTE: this field is null when we are not caching "this" which happens when
/// - not optimizing
/// - method is not capturing "this" at all
/// - containing type is a struct
/// (we could cache "this" as a ref local for struct containers,
/// but such caching would not save as much indirection and could actually
/// be done at JIT level, possibly more efficiently)
/// </summary>
protected
readonly
LocalSymbol
cachedThis
;
private
int
_nextState
;
/// <summary>
...
...
@@ -136,6 +150,18 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter
{
this
.
proxies
.
Add
(
proxy
.
Key
,
proxy
.
Value
);
}
// create cache local for reference type "this" in Release
var
thisParameter
=
originalMethod
.
ThisParameter
;
CapturedSymbolReplacement
thisProxy
;
if
((
object
)
thisParameter
!=
null
&&
thisParameter
.
Type
.
IsReferenceType
&&
proxies
.
TryGetValue
(
thisParameter
,
out
thisProxy
)
&&
F
.
Compilation
.
Options
.
OptimizationLevel
==
OptimizationLevel
.
Release
)
{
BoundExpression
thisProxyReplacement
=
thisProxy
.
Replacement
(
F
.
Syntax
,
frameType
=>
F
.
This
());
this
.
cachedThis
=
F
.
SynthesizedLocal
(
thisProxyReplacement
.
Type
,
syntax
:
F
.
Syntax
,
kind
:
SynthesizedLocalKind
.
FrameCache
);
}
}
protected
override
bool
NeedsProxy
(
Symbol
localOrParameter
)
...
...
@@ -739,8 +765,28 @@ public override BoundNode VisitTryStatement(BoundTryStatement node)
return
result
;
}
p
ublic
override
BoundNode
VisitThisReference
(
BoundThisReference
node
)
p
rotected
BoundStatement
CacheThisIfNeeded
(
)
{
// restore "this" cache, if there is a cache
if
((
object
)
this
.
cachedThis
!=
null
)
{
CapturedSymbolReplacement
proxy
=
proxies
[
this
.
OriginalMethod
.
ThisParameter
];
var
fetchThis
=
proxy
.
Replacement
(
F
.
Syntax
,
frameType
=>
F
.
This
());
return
F
.
Assignment
(
F
.
Local
(
this
.
cachedThis
),
fetchThis
);
}
// do nothing
return
F
.
StatementList
();
}
public
sealed
override
BoundNode
VisitThisReference
(
BoundThisReference
node
)
{
// if "this" is cached, return it.
if
((
object
)
this
.
cachedThis
!=
null
)
{
return
F
.
Local
(
this
.
cachedThis
);
}
var
thisParameter
=
this
.
OriginalMethod
.
ThisParameter
;
CapturedSymbolReplacement
proxy
;
if
((
object
)
thisParameter
==
null
||
!
proxies
.
TryGetValue
(
thisParameter
,
out
proxy
))
...
...
@@ -768,6 +814,13 @@ public override BoundNode VisitThisReference(BoundThisReference node)
public
override
BoundNode
VisitBaseReference
(
BoundBaseReference
node
)
{
// TODO: fix up the type of the resulting node to be the base type
// if "this" is cached, return it.
if
((
object
)
this
.
cachedThis
!=
null
)
{
return
F
.
Local
(
this
.
cachedThis
);
}
CapturedSymbolReplacement
proxy
=
proxies
[
this
.
OriginalMethod
.
ThisParameter
];
Debug
.
Assert
(
proxy
!=
null
);
return
proxy
.
Replacement
(
F
.
Syntax
,
frameType
=>
F
.
This
());
...
...
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineFieldSymbol.cs
浏览文件 @
bf8d2ec7
...
...
@@ -14,6 +14,7 @@ namespace Microsoft.CodeAnalysis.CSharp
internal
sealed
class
StateMachineFieldSymbol
:
SynthesizedFieldSymbolBase
,
ISynthesizedMethodBodyImplementationSymbol
{
private
readonly
TypeSymbol
_type
;
private
readonly
bool
_isThis
;
// -1 if the field doesn't represent a long-lived local or an awaiter.
internal
readonly
int
SlotIndex
;
...
...
@@ -21,9 +22,10 @@ internal sealed class StateMachineFieldSymbol : SynthesizedFieldSymbolBase, ISyn
internal
readonly
LocalSlotDebugInfo
SlotDebugInfo
;
// Some fields need to be public since they are initialized directly by the kickoff method.
public
StateMachineFieldSymbol
(
NamedTypeSymbol
stateMachineType
,
TypeSymbol
type
,
string
name
,
bool
isPublic
)
public
StateMachineFieldSymbol
(
NamedTypeSymbol
stateMachineType
,
TypeSymbol
type
,
string
name
,
bool
isPublic
,
bool
isThis
)
:
this
(
stateMachineType
,
type
,
name
,
new
LocalSlotDebugInfo
(
SynthesizedLocalKind
.
LoweringTemp
,
LocalDebugId
.
None
),
slotIndex
:
-
1
,
isPublic
:
isPublic
)
{
_isThis
=
isThis
;
}
public
StateMachineFieldSymbol
(
NamedTypeSymbol
stateMachineType
,
TypeSymbol
type
,
string
name
,
SynthesizedLocalKind
synthesizedKind
,
int
slotIndex
,
bool
isPublic
)
...
...
@@ -61,5 +63,10 @@ IMethodSymbol ISynthesizedMethodBodyImplementationSymbol.Method
{
get
{
return
((
ISynthesizedMethodBodyImplementationSymbol
)
ContainingSymbol
).
Method
;
}
}
internal
override
bool
IsCapturedFrame
{
get
{
return
_isThis
;
}
}
}
}
src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
浏览文件 @
bf8d2ec7
...
...
@@ -208,13 +208,13 @@ protected BoundStatement Rewrite()
if
(
parameter
.
IsThis
)
{
var
containingType
=
method
.
ContainingType
;
var
proxyField
=
F
.
StateMachineField
(
containingType
,
GeneratedNames
.
ThisProxyFieldName
(),
isPublic
:
true
);
var
proxyField
=
F
.
StateMachineField
(
containingType
,
GeneratedNames
.
ThisProxyFieldName
(),
isPublic
:
true
,
isThis
:
true
);
proxiesBuilder
.
Add
(
parameter
,
new
CapturedToStateMachineFieldReplacement
(
proxyField
,
isReusable
:
false
));
if
(
PreserveInitialParameterValues
)
{
var
initialThis
=
containingType
.
IsStructType
()
?
F
.
StateMachineField
(
containingType
,
GeneratedNames
.
StateMachineThisParameterProxyName
(),
isPublic
:
true
)
:
proxyField
;
F
.
StateMachineField
(
containingType
,
GeneratedNames
.
StateMachineThisParameterProxyName
(),
isPublic
:
true
,
isThis
:
true
)
:
proxyField
;
initialParameters
.
Add
(
parameter
,
new
CapturedToStateMachineFieldReplacement
(
initialThis
,
isReusable
:
false
));
}
...
...
src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
浏览文件 @
bf8d2ec7
...
...
@@ -205,9 +205,9 @@ public BoundHoistedFieldAccess HoistedField(FieldSymbol field)
return
new
BoundHoistedFieldAccess
(
Syntax
,
field
,
field
.
Type
);
}
public
StateMachineFieldSymbol
StateMachineField
(
TypeSymbol
type
,
string
name
,
bool
isPublic
=
false
)
public
StateMachineFieldSymbol
StateMachineField
(
TypeSymbol
type
,
string
name
,
bool
isPublic
=
false
,
bool
isThis
=
false
)
{
var
result
=
new
StateMachineFieldSymbol
(
CurrentType
,
type
,
name
,
isPublic
);
var
result
=
new
StateMachineFieldSymbol
(
CurrentType
,
type
,
name
,
isPublic
,
isThis
);
AddField
(
CurrentType
,
result
);
return
result
;
}
...
...
@@ -423,6 +423,11 @@ public BoundBlock Block(ImmutableArray<LocalSymbol> locals, ImmutableArray<Local
return
new
BoundBlock
(
Syntax
,
locals
,
localFunctions
,
statements
)
{
WasCompilerGenerated
=
true
};
}
public
BoundStatementList
StatementList
()
{
return
StatementList
(
ImmutableArray
<
BoundStatement
>.
Empty
);
}
public
BoundStatementList
StatementList
(
ImmutableArray
<
BoundStatement
>
statements
)
{
return
new
BoundStatementList
(
Syntax
,
statements
)
{
WasCompilerGenerated
=
true
};
...
...
src/Compilers/CSharp/Test/Emit/BreakingChanges.cs
浏览文件 @
bf8d2ec7
...
...
@@ -1149,7 +1149,102 @@ public IEnumerable Foo()
}
"
;
// Native print "++ ++ EX 2"
CompileAndVerify
(
source
,
expectedOutput
:
" ++ EX 1"
);
var
verifier
=
CompileAndVerify
(
source
,
expectedOutput
:
" ++ EX 1"
);
// must not load "<>4__this"
verifier
.
VerifyIL
(
"Program.test.<Foo>d__1.System.Collections.IEnumerator.MoveNext()"
,
@"
{
// Code size 101 (0x65)
.maxstack 2
.locals init (bool V_0,
int V_1)
.try
{
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.test.<Foo>d__1.<>1__state""
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: brfalse.s IL_0012
IL_000a: ldloc.1
IL_000b: ldc.i4.1
IL_000c: beq.s IL_0033
IL_000e: ldc.i4.0
IL_000f: stloc.0
IL_0010: leave.s IL_0063
IL_0012: ldarg.0
IL_0013: ldc.i4.m1
IL_0014: stfld ""int Program.test.<Foo>d__1.<>1__state""
IL_0019: ldarg.0
IL_001a: ldc.i4.s -3
IL_001c: stfld ""int Program.test.<Foo>d__1.<>1__state""
IL_0021: ldarg.0
IL_0022: ldnull
IL_0023: stfld ""object Program.test.<Foo>d__1.<>2__current""
IL_0028: ldarg.0
IL_0029: ldc.i4.1
IL_002a: stfld ""int Program.test.<Foo>d__1.<>1__state""
IL_002f: ldc.i4.1
IL_0030: stloc.0
IL_0031: leave.s IL_0063
IL_0033: ldarg.0
IL_0034: ldc.i4.s -3
IL_0036: stfld ""int Program.test.<Foo>d__1.<>1__state""
.try
{
IL_003b: ldc.i4.0
IL_003c: stloc.0
IL_003d: leave.s IL_004a
}
catch object
{
IL_003f: pop
IL_0040: leave.s IL_0042
}
IL_0042: ldarg.0
IL_0043: call ""void Program.test.<Foo>d__1.<>m__Finally1()""
IL_0048: br.s IL_0052
IL_004a: ldarg.0
IL_004b: call ""void Program.test.<Foo>d__1.<>m__Finally1()""
IL_0050: leave.s IL_0063
IL_0052: leave.s IL_005b
}
fault
{
IL_0054: ldarg.0
IL_0055: call ""void Program.test.<Foo>d__1.Dispose()""
IL_005a: endfinally
}
IL_005b: ldarg.0
IL_005c: call ""void Program.test.<Foo>d__1.Dispose()""
IL_0061: ldc.i4.1
IL_0062: stloc.0
IL_0063: ldloc.0
IL_0064: ret
}
"
);
// must load "<>4__this"
verifier
.
VerifyIL
(
"Program.test.<Foo>d__1.<>m__Finally1()"
,
@"
{
// Code size 42 (0x2a)
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldc.i4.m1
IL_0002: stfld ""int Program.test.<Foo>d__1.<>1__state""
IL_0007: ldarg.0
IL_0008: ldfld ""Program.test Program.test.<Foo>d__1.<>4__this""
IL_000d: ldstr ""++ ""
IL_0012: call ""void System.Console.Write(string)""
IL_0017: dup
IL_0018: ldfld ""int Program.test.count""
IL_001d: ldc.i4.1
IL_001e: add
IL_001f: stfld ""int Program.test.count""
IL_0024: newobj ""System.Exception..ctor()""
IL_0029: throw
}
"
);
}
[
Fact
,
WorkItem
(
530587
,
"http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530587"
)]
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs
浏览文件 @
bf8d2ec7
...
...
@@ -499,7 +499,397 @@ public static void Main()
var
expected
=
@"
42
"
;
CompileAndVerify
(
source
,
expectedOutput
:
expected
);
var
verifier
=
CompileAndVerify
(
source
,
expectedOutput
:
expected
);
verifier
.
VerifyIL
(
"C.<F>d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()"
,
@"
{
// Code size 199 (0xc7)
.maxstack 3
.locals init (int V_0,
C V_1,
int V_2,
C.<>c__DisplayClass1_0 V_3, //CS$<>8__locals0
System.Runtime.CompilerServices.TaskAwaiter<int> V_4,
System.Exception V_5)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__1.<>1__state""
IL_0006: stloc.0
IL_0007: ldarg.0
IL_0008: ldfld ""C C.<F>d__1.<>4__this""
IL_000d: stloc.1
.try
{
IL_000e: ldloc.0
IL_000f: brfalse.s IL_006a
IL_0011: newobj ""C.<>c__DisplayClass1_0..ctor()""
IL_0016: stloc.3
IL_0017: ldloc.3
IL_0018: ldloc.1
IL_0019: ldfld ""int C.x""
IL_001e: stfld ""int C.<>c__DisplayClass1_0.c""
IL_0023: call ""System.Threading.Tasks.TaskFactory System.Threading.Tasks.Task.Factory.get""
IL_0028: ldloc.3
IL_0029: ldftn ""int C.<>c__DisplayClass1_0.<F>b__0()""
IL_002f: newobj ""System.Func<int>..ctor(object, System.IntPtr)""
IL_0034: callvirt ""System.Threading.Tasks.Task<int> System.Threading.Tasks.TaskFactory.StartNew<int>(System.Func<int>)""
IL_0039: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_003e: stloc.s V_4
IL_0040: ldloca.s V_4
IL_0042: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_0047: brtrue.s IL_0087
IL_0049: ldarg.0
IL_004a: ldc.i4.0
IL_004b: dup
IL_004c: stloc.0
IL_004d: stfld ""int C.<F>d__1.<>1__state""
IL_0052: ldarg.0
IL_0053: ldloc.s V_4
IL_0055: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> C.<F>d__1.<>u__1""
IL_005a: ldarg.0
IL_005b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__1.<>t__builder""
IL_0060: ldloca.s V_4
IL_0062: ldarg.0
IL_0063: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, C.<F>d__1>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref C.<F>d__1)""
IL_0068: leave.s IL_00c6
IL_006a: ldarg.0
IL_006b: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> C.<F>d__1.<>u__1""
IL_0070: stloc.s V_4
IL_0072: ldarg.0
IL_0073: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> C.<F>d__1.<>u__1""
IL_0078: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_007e: ldarg.0
IL_007f: ldc.i4.m1
IL_0080: dup
IL_0081: stloc.0
IL_0082: stfld ""int C.<F>d__1.<>1__state""
IL_0087: ldloca.s V_4
IL_0089: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_008e: ldloca.s V_4
IL_0090: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0096: stloc.2
IL_0097: leave.s IL_00b2
}
catch System.Exception
{
IL_0099: stloc.s V_5
IL_009b: ldarg.0
IL_009c: ldc.i4.s -2
IL_009e: stfld ""int C.<F>d__1.<>1__state""
IL_00a3: ldarg.0
IL_00a4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__1.<>t__builder""
IL_00a9: ldloc.s V_5
IL_00ab: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
IL_00b0: leave.s IL_00c6
}
IL_00b2: ldarg.0
IL_00b3: ldc.i4.s -2
IL_00b5: stfld ""int C.<F>d__1.<>1__state""
IL_00ba: ldarg.0
IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__1.<>t__builder""
IL_00c0: ldloc.2
IL_00c1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
IL_00c6: ret
}
"
);
}
[
Fact
]
public
void
AsyncWithThisRef01
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class C
{
int x => 14;
public async Task<int> F()
{
int c = this.x;
await Task.Yield();
c += this.x;
await Task.Yield();
c += this.x;
await Task.Yield();
await Task.Yield();
await Task.Yield();
return c;
}
}
class Test
{
public static void Main()
{
Task<int> t = new C().F();
t.Wait(1000 * 60);
Console.WriteLine(t.Result);
}
}"
;
var
expected
=
@"
42
"
;
var
verifier
=
CompileAndVerify
(
source
,
expectedOutput
:
expected
);
verifier
.
VerifyIL
(
"C.<F>d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()"
,
@"
{
// Code size 652 (0x28c)
.maxstack 3
.locals init (int V_0,
C V_1,
int V_2,
System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_3,
System.Runtime.CompilerServices.YieldAwaitable V_4,
System.Exception V_5)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__2.<>1__state""
IL_0006: stloc.0
IL_0007: ldarg.0
IL_0008: ldfld ""C C.<F>d__2.<>4__this""
IL_000d: stloc.1
.try
{
IL_000e: ldloc.0
IL_000f: switch (
IL_006f,
IL_00e8,
IL_0161,
IL_01c7,
IL_022a)
IL_0028: ldarg.0
IL_0029: ldloc.1
IL_002a: call ""int C.x.get""
IL_002f: stfld ""int C.<F>d__2.<c>5__1""
IL_0034: call ""System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()""
IL_0039: stloc.s V_4
IL_003b: ldloca.s V_4
IL_003d: call ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()""
IL_0042: stloc.3
IL_0043: ldloca.s V_3
IL_0045: call ""bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get""
IL_004a: brtrue.s IL_008b
IL_004c: ldarg.0
IL_004d: ldc.i4.0
IL_004e: dup
IL_004f: stloc.0
IL_0050: stfld ""int C.<F>d__2.<>1__state""
IL_0055: ldarg.0
IL_0056: ldloc.3
IL_0057: stfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_005c: ldarg.0
IL_005d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_0062: ldloca.s V_3
IL_0064: ldarg.0
IL_0065: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, C.<F>d__2>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.<F>d__2)""
IL_006a: leave IL_028b
IL_006f: ldarg.0
IL_0070: ldfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_0075: stloc.3
IL_0076: ldarg.0
IL_0077: ldflda ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_007c: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_0082: ldarg.0
IL_0083: ldc.i4.m1
IL_0084: dup
IL_0085: stloc.0
IL_0086: stfld ""int C.<F>d__2.<>1__state""
IL_008b: ldloca.s V_3
IL_008d: call ""void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()""
IL_0092: ldloca.s V_3
IL_0094: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_009a: ldarg.0
IL_009b: ldarg.0
IL_009c: ldfld ""int C.<F>d__2.<c>5__1""
IL_00a1: ldloc.1
IL_00a2: call ""int C.x.get""
IL_00a7: add
IL_00a8: stfld ""int C.<F>d__2.<c>5__1""
IL_00ad: call ""System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()""
IL_00b2: stloc.s V_4
IL_00b4: ldloca.s V_4
IL_00b6: call ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()""
IL_00bb: stloc.3
IL_00bc: ldloca.s V_3
IL_00be: call ""bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get""
IL_00c3: brtrue.s IL_0104
IL_00c5: ldarg.0
IL_00c6: ldc.i4.1
IL_00c7: dup
IL_00c8: stloc.0
IL_00c9: stfld ""int C.<F>d__2.<>1__state""
IL_00ce: ldarg.0
IL_00cf: ldloc.3
IL_00d0: stfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_00d5: ldarg.0
IL_00d6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_00db: ldloca.s V_3
IL_00dd: ldarg.0
IL_00de: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, C.<F>d__2>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.<F>d__2)""
IL_00e3: leave IL_028b
IL_00e8: ldarg.0
IL_00e9: ldfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_00ee: stloc.3
IL_00ef: ldarg.0
IL_00f0: ldflda ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_00f5: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_00fb: ldarg.0
IL_00fc: ldc.i4.m1
IL_00fd: dup
IL_00fe: stloc.0
IL_00ff: stfld ""int C.<F>d__2.<>1__state""
IL_0104: ldloca.s V_3
IL_0106: call ""void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()""
IL_010b: ldloca.s V_3
IL_010d: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_0113: ldarg.0
IL_0114: ldarg.0
IL_0115: ldfld ""int C.<F>d__2.<c>5__1""
IL_011a: ldloc.1
IL_011b: call ""int C.x.get""
IL_0120: add
IL_0121: stfld ""int C.<F>d__2.<c>5__1""
IL_0126: call ""System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()""
IL_012b: stloc.s V_4
IL_012d: ldloca.s V_4
IL_012f: call ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()""
IL_0134: stloc.3
IL_0135: ldloca.s V_3
IL_0137: call ""bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get""
IL_013c: brtrue.s IL_017d
IL_013e: ldarg.0
IL_013f: ldc.i4.2
IL_0140: dup
IL_0141: stloc.0
IL_0142: stfld ""int C.<F>d__2.<>1__state""
IL_0147: ldarg.0
IL_0148: ldloc.3
IL_0149: stfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_014e: ldarg.0
IL_014f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_0154: ldloca.s V_3
IL_0156: ldarg.0
IL_0157: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, C.<F>d__2>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.<F>d__2)""
IL_015c: leave IL_028b
IL_0161: ldarg.0
IL_0162: ldfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_0167: stloc.3
IL_0168: ldarg.0
IL_0169: ldflda ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_016e: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_0174: ldarg.0
IL_0175: ldc.i4.m1
IL_0176: dup
IL_0177: stloc.0
IL_0178: stfld ""int C.<F>d__2.<>1__state""
IL_017d: ldloca.s V_3
IL_017f: call ""void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()""
IL_0184: ldloca.s V_3
IL_0186: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_018c: call ""System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()""
IL_0191: stloc.s V_4
IL_0193: ldloca.s V_4
IL_0195: call ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()""
IL_019a: stloc.3
IL_019b: ldloca.s V_3
IL_019d: call ""bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get""
IL_01a2: brtrue.s IL_01e3
IL_01a4: ldarg.0
IL_01a5: ldc.i4.3
IL_01a6: dup
IL_01a7: stloc.0
IL_01a8: stfld ""int C.<F>d__2.<>1__state""
IL_01ad: ldarg.0
IL_01ae: ldloc.3
IL_01af: stfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_01b4: ldarg.0
IL_01b5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_01ba: ldloca.s V_3
IL_01bc: ldarg.0
IL_01bd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, C.<F>d__2>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.<F>d__2)""
IL_01c2: leave IL_028b
IL_01c7: ldarg.0
IL_01c8: ldfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_01cd: stloc.3
IL_01ce: ldarg.0
IL_01cf: ldflda ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_01d4: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_01da: ldarg.0
IL_01db: ldc.i4.m1
IL_01dc: dup
IL_01dd: stloc.0
IL_01de: stfld ""int C.<F>d__2.<>1__state""
IL_01e3: ldloca.s V_3
IL_01e5: call ""void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()""
IL_01ea: ldloca.s V_3
IL_01ec: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_01f2: call ""System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()""
IL_01f7: stloc.s V_4
IL_01f9: ldloca.s V_4
IL_01fb: call ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()""
IL_0200: stloc.3
IL_0201: ldloca.s V_3
IL_0203: call ""bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get""
IL_0208: brtrue.s IL_0246
IL_020a: ldarg.0
IL_020b: ldc.i4.4
IL_020c: dup
IL_020d: stloc.0
IL_020e: stfld ""int C.<F>d__2.<>1__state""
IL_0213: ldarg.0
IL_0214: ldloc.3
IL_0215: stfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_021a: ldarg.0
IL_021b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_0220: ldloca.s V_3
IL_0222: ldarg.0
IL_0223: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, C.<F>d__2>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.<F>d__2)""
IL_0228: leave.s IL_028b
IL_022a: ldarg.0
IL_022b: ldfld ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_0230: stloc.3
IL_0231: ldarg.0
IL_0232: ldflda ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.<F>d__2.<>u__1""
IL_0237: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_023d: ldarg.0
IL_023e: ldc.i4.m1
IL_023f: dup
IL_0240: stloc.0
IL_0241: stfld ""int C.<F>d__2.<>1__state""
IL_0246: ldloca.s V_3
IL_0248: call ""void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()""
IL_024d: ldloca.s V_3
IL_024f: initobj ""System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter""
IL_0255: ldarg.0
IL_0256: ldfld ""int C.<F>d__2.<c>5__1""
IL_025b: stloc.2
IL_025c: leave.s IL_0277
}
catch System.Exception
{
IL_025e: stloc.s V_5
IL_0260: ldarg.0
IL_0261: ldc.i4.s -2
IL_0263: stfld ""int C.<F>d__2.<>1__state""
IL_0268: ldarg.0
IL_0269: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_026e: ldloc.s V_5
IL_0270: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
IL_0275: leave.s IL_028b
}
IL_0277: ldarg.0
IL_0278: ldc.i4.s -2
IL_027a: stfld ""int C.<F>d__2.<>1__state""
IL_027f: ldarg.0
IL_0280: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> C.<F>d__2.<>t__builder""
IL_0285: ldloc.2
IL_0286: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
IL_028b: ret
}
"
);
}
[
Fact
]
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs
浏览文件 @
bf8d2ec7
...
...
@@ -3970,7 +3970,7 @@ .maxstack 4
IL_000d: ldarg.0
IL_000e: ldfld ""Script <<Initialize>>d__0.<>4__this""
IL_0013: ldflda ""int x1""
IL_0018: call
virt
""(int, int) M(out int)""
IL_0018: call
""(int, int) M(out int)""
IL_001d: dup
IL_001e: ldfld ""int System.ValueTuple<int, int>.Item1""
IL_0023: stloc.2
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs
浏览文件 @
bf8d2ec7
此差异已折叠。
点击以展开。
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
浏览文件 @
bf8d2ec7
...
...
@@ -2884,7 +2884,7 @@ .locals init (int V_0)
IL_0020: ldarg.0
IL_0021: ldarg.0
IL_0022: ldfld ""C C.<F>d__0.<>4__this""
IL_0027: call
virt
""System.Collections.Generic.IEnumerable<int> C.F()""
IL_0027: call
""System.Collections.Generic.IEnumerable<int> C.F()""
IL_002c: stfld ""System.Collections.Generic.IEnumerable<int> C.<F>d__0.<>s__1""
IL_0031: ldarg.0
IL_0032: ldc.i4.0
...
...
@@ -2989,7 +2989,7 @@ .maxstack 3
-IL_0012: ldarg.0
IL_0013: ldarg.0
IL_0014: ldfld ""C C.<F>d__0.<>4__this""
IL_0019: call
virt
""System.Threading.Tasks.Task<int> C.F()""
IL_0019: call
""System.Threading.Tasks.Task<int> C.F()""
IL_001e: stfld ""System.Threading.Tasks.Task<int> C.<F>d__0.<>s__1""
IL_0023: ldarg.0
IL_0024: ldc.i4.0
...
...
@@ -3025,7 +3025,7 @@ .maxstack 3
IL_005b: stfld ""System.Threading.Tasks.Task<int> C.<F>d__0.<>s__1""
-IL_0060: ldarg.0
IL_0061: ldfld ""C C.<F>d__0.<>4__this""
IL_0066: call
virt
""System.Threading.Tasks.Task<int> C.F()""
IL_0066: call
""System.Threading.Tasks.Task<int> C.F()""
IL_006b: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0070: stloc.2
~IL_0071: ldloca.s V_2
...
...
src/Compilers/Core/Portable/SynthesizedLocalKind.cs
浏览文件 @
bf8d2ec7
...
...
@@ -26,6 +26,12 @@ namespace Microsoft.CodeAnalysis
/// </remarks>
internal
enum
SynthesizedLocalKind
{
/// <summary>
/// Temp created for caching "this".
/// Technically it is long-lived, but will happen only in optimized code.
/// </summary>
FrameCache
=
-
5
,
/// <summary>
/// Temp created for pattern matching by type.
/// </summary>
...
...
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Await.vb
浏览文件 @
bf8d2ec7
...
...
@@ -73,7 +73,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
builder
.
AddStatement
(
Me
.
F
.
If
(
condition
:
=
Me
.
F
.
Convert
(
Me
.
F
.
SpecialType
(
SpecialType
.
System_Boolean
),
rewrittenIsCompleted
),
thenClause
:
=
Me
.
F
.
Block
(),
thenClause
:
=
Me
.
F
.
StatementList
(),
elseClause
:
=
awaitForIncompleteTask
))
Else
' regular case
...
...
src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb
浏览文件 @
bf8d2ec7
...
...
@@ -108,7 +108,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private
Function
HandleReturn
()
As
BoundStatement
If
Me
.
_exitLabel
Is
Nothing
Then
' did not see indirect returns
Return
F
.
Block
()
Return
F
.
StatementList
()
Else
' _methodValue = False
' exitlabel:
...
...
src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb
浏览文件 @
bf8d2ec7
...
...
@@ -216,7 +216,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
F
.
Assignment
(
F
.
Local
(
resultVariable
,
True
),
F
.
Me
),
If
(
Method
.
IsShared
OrElse
Method
.
MeParameter
.
Type
.
IsReferenceType
,
F
.
Goto
(
thisInitialized
),
DirectCast
(
F
.
Block
(),
BoundStatement
))
DirectCast
(
F
.
StatementList
(),
BoundStatement
))
),
elseClause
:
=
F
.
Assignment
(
F
.
Local
(
resultVariable
,
True
),
F
.
[
New
]
(
StateMachineType
.
Constructor
,
F
.
Literal
(
0
)))
...
...
src/Compilers/VisualBasic/Portable/Lowering/SyntheticBoundNodeFactory.vb
浏览文件 @
bf8d2ec7
...
...
@@ -357,6 +357,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
Block
(
locals
,
ImmutableArray
.
Create
(
Of
BoundStatement
)(
statements
))
End
Function
Public
Function
StatementList
()
As
BoundStatementList
Return
StatementList
(
ImmutableArray
(
Of
BoundStatement
).
Empty
)
End
Function
Public
Function
StatementList
(
statements
As
ImmutableArray
(
Of
BoundStatement
))
As
BoundStatementList
Dim
boundNode
As
New
BoundStatementList
(
Syntax
,
statements
)
boundNode
.
SetWasCompilerGenerated
()
...
...
src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs
浏览文件 @
bf8d2ec7
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录