Browse Source

[async] Allow splitting awaiter variables.

pull/850/head
Daniel Grunwald 8 years ago
parent
commit
f5d907e0ce
  1. 2
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  2. 12
      ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs

2
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -686,7 +686,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -686,7 +686,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
block.Instructions.RemoveAt(block.Instructions.Count - 2); // remove if (isCompleted)
((Branch)block.Instructions.Last()).TargetBlock = completedBlock; // instead, directly jump to completed block
Await awaitInst = new Await(getAwaiterCall.Arguments.Single());
awaitInst.GetResultMethod = ((CallInstruction)getResultCall).Method;
awaitInst.GetResultMethod = getResultCall.Method;
awaitInst.GetAwaiterMethod = getAwaiterCall.Method;
getResultCall.ReplaceWith(awaitInst);

12
ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs

@ -54,9 +54,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -54,9 +54,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
return true;
case VariableKind.StackSlot:
// stack slots: are already split by construction,
// except for the locals-turned-stackslots in async functions
if (v.Function.IsAsync)
goto case VariableKind.Local;
else
return false;
default:
// parameters: avoid splitting parameters
// stack slots: are already split by construction
// pinned locals: must not split (doing so would extend the life of the pin to the end of the method)
return false;
}
@ -69,6 +75,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -69,6 +75,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
case LdFlda ldflda:
return AddressUsedOnlyForReading(ldflda);
case Await await:
// Not strictly true as GetAwaiter() could have side-effects,
// but we need to split awaiter variables to make async/await pretty.
return true;
case Call call:
if (call.Method.DeclaringTypeDefinition.KnownTypeCode == TypeSystem.KnownTypeCode.NullableOfT) {
switch (call.Method.Name) {

Loading…
Cancel
Save