Skip to content
Permalink
Browse files

Improve async/await decompilation when reference assemblies are missing

  • Loading branch information...
dgrunwald committed Sep 29, 2019
1 parent f8ee7c2 commit 67fa24b09f4c58e208d5ccb22b3e7145665c8ba4
@@ -53,7 +53,7 @@ function gitCommitHash() {
}

function gitBranch() {
if (-not ((Test-Dir ".git") -and (Find-Git))) {
if (-not ((Test-Dir ".git" -or Test-File ".git") -and (Find-Git))) {
return "no-branch";
}

@@ -998,7 +998,7 @@ void DetectAwaitPattern(Block block)
// continue matching call get_IsCompleted(ldloca awaiterVar)
if (!MatchCall(condition, "get_IsCompleted", out var isCompletedArgs) || isCompletedArgs.Count != 1)
return;
if (!isCompletedArgs[0].MatchLdLocRef(awaiterVar))
if (!UnwrapConvUnknown(isCompletedArgs[0]).MatchLdLocRef(awaiterVar))
return;
// Check awaitBlock and resumeBlock:
if (!awaitBlocks.TryGetValue(awaitBlock, out var awaitBlockData))
@@ -1016,14 +1016,14 @@ void DetectAwaitPattern(Block block)
return;
if (!MatchCall(getResultCall, "GetResult", out var getResultArgs) || getResultArgs.Count != 1)
return;
if (!getResultArgs[0].MatchLdLocRef(awaiterVar))
if (!UnwrapConvUnknown(getResultArgs[0]).MatchLdLocRef(awaiterVar))
return;
// All checks successful, let's transform.
context.Step("Transform await pattern", block);
block.Instructions.RemoveAt(block.Instructions.Count - 3); // remove getAwaiter call
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());
Await awaitInst = new Await(UnwrapConvUnknown(getAwaiterCall.Arguments.Single()));
awaitInst.GetResultMethod = getResultCall.Method;
awaitInst.GetAwaiterMethod = getAwaiterCall.Method;
getResultCall.ReplaceWith(awaitInst);
@@ -1035,7 +1035,15 @@ void DetectAwaitPattern(Block block)
}
}
}


static ILInstruction UnwrapConvUnknown(ILInstruction inst)
{
if (inst is Conv conv && conv.TargetType == PrimitiveType.Unknown) {
return conv.Argument;
}
return inst;
}

bool CheckAwaitBlock(Block block, out Block resumeBlock, out IField stackField)
{
// awaitBlock:

0 comments on commit 67fa24b

Please sign in to comment.
You can’t perform that action at this time.