diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index ca0d812fc..55735e517 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1760,7 +1760,7 @@ namespace ICSharpCode.Decompiler.CSharp } return new UnaryOperatorExpression(UnaryOperatorType.Await, value.Expression) .WithILInstruction(inst) - .WithRR(new ResolveResult(inst?.GetResultMethod.ReturnType ?? SpecialType.UnknownType)); + .WithRR(new ResolveResult(inst.GetResultMethod?.ReturnType ?? SpecialType.UnknownType)); } protected internal override TranslatedExpression VisitInvalidBranch(InvalidBranch inst, TranslationContext context) diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 64614fddd..3298af964 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -81,11 +81,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow } InlineBodyOfMoveNext(function); - - // Copy-propagate temporaries holding a copy of 'this'. - foreach (var stloc in function.Descendants.OfType().Where(s => s.Variable.IsSingleDefinition && s.Value.MatchLdThis()).ToList()) { - CopyPropagation.Propagate(stloc, context); - } + CleanUpBodyOfMoveNext(function); AnalyzeStateMachine(function); DetectAwaitPattern(function); @@ -101,6 +97,26 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow function.RunTransforms(CSharpDecompiler.EarlyILTransforms(), context); } + private void CleanUpBodyOfMoveNext(ILFunction function) + { + context.StepStartGroup("CleanUpBodyOfMoveNext", function); + // Simplify stobj(ldloca) -> stloc + foreach (var stobj in function.Descendants.OfType()) { + ExpressionTransforms.StObjToStLoc(stobj, context); + } + + // Copy-propagate temporaries holding a copy of 'this'. + foreach (var stloc in function.Descendants.OfType().Where(s => s.Variable.IsSingleDefinition && s.Value.MatchLdThis()).ToList()) { + CopyPropagation.Propagate(stloc, context); + } + new RemoveDeadVariableInit().Run(function, context); + // Run inlining, but don't remove dead variables (they might get revived by TranslateFieldsToLocalAccess) + foreach (var block in function.Descendants.OfType()) { + ILInlining.InlineAllInBlock(block, context); + } + context.StepEndGroup(); + } + #region MatchTaskCreationPattern bool MatchTaskCreationPattern(ILFunction function) { @@ -717,7 +733,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow pos++; } if (block.Instructions[pos] is StLoc stlocCachedState) { - if (stlocCachedState.Variable.Kind == VariableKind.Local && stlocCachedState.Variable.Index == cachedStateVar.Index) { + if (stlocCachedState.Variable.Kind == VariableKind.Local && stlocCachedState.Variable.Index == cachedStateVar?.Index) { if (stlocCachedState.Value.MatchLdLoc(m1Var) || stlocCachedState.Value.MatchLdcI4(initialState)) pos++; } diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index f2d90c92f..00995b10d 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -237,7 +237,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms && TypeUtils.IsCompatibleTypeForMemoryAccess(new ByReferenceType(v.Type), inst.Type) && inst.UnalignedPrefix == 0 && !inst.IsVolatile) { - context.Step("stobj(ldloca(v), ...) => stloc(v, ...)", inst); + context.Step($"stobj(ldloca {v.Name}, ...) => stloc {v.Name}(...)", inst); inst.ReplaceWith(new StLoc(v, inst.Value)); return true; } diff --git a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs index de7f53dfe..1f47ac457 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs @@ -28,24 +28,20 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// public class ILInlining : IILTransform, IBlockTransform { - ILTransformContext context; - public void Run(ILFunction function, ILTransformContext context) { - this.context = context; foreach (var block in function.Descendants.OfType()) { - InlineAllInBlock(block); + InlineAllInBlock(block, context); } function.Variables.RemoveDead(); } public void Run(Block block, BlockTransformContext context) { - this.context = context; - InlineAllInBlock(block); + InlineAllInBlock(block, context); } - public bool InlineAllInBlock(Block block) + public static bool InlineAllInBlock(Block block, ILTransformContext context) { bool modified = false; int i = 0;