public static void RunStep2(DecompilerContext context, ILBlock method) { if (context.CurrentMethodIsAsync) { Step2(method.Body); ILAstOptimizer.RemoveRedundantCode(method); // Repeat the inlining/copy propagation optimization because the conversion of field access // to local variables can open up additional inlining possibilities. ILInlining inlining = new ILInlining(method); inlining.InlineAllVariables(); inlining.CopyPropagation(); } }
/// <summary> /// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step. /// </summary> ILBlock CreateILAst(MethodDefinition method) { if (method == null || !method.HasBody) { throw new SymbolicAnalysisFailedException(); } ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); ilMethod.Body = astBuilder.Build(method, true, context); ILAstOptimizer optimizer = new ILAstOptimizer(); optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn); return(ilMethod); }
public static void RunStep1(DecompilerContext context, ILBlock method) { if (!context.Settings.AsyncAwait) { return; // abort if async decompilation is disabled } var yrd = new AsyncDecompiler(); yrd.context = context; if (!yrd.MatchTaskCreationPattern(method)) { return; } #if DEBUG if (Debugger.IsAttached) { yrd.Run(); } else { #endif try { yrd.Run(); } catch (SymbolicAnalysisFailedException) { return; } #if DEBUG } #endif context.CurrentMethodIsAsync = true; method.Body.Clear(); method.EntryGoto = null; method.Body.AddRange(yrd.newTopLevelBody); ILAstOptimizer.RemoveRedundantCode(method); }
/// <summary> /// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step. /// </summary> ILBlock CreateILAst(MethodDefinition method) { if (method == null || !method.HasBody) throw new SymbolicAnalysisFailedException(); ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); ilMethod.Body = astBuilder.Build(method, true, context); ILAstOptimizer optimizer = new ILAstOptimizer(); optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn); return ilMethod; }
public BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters) { if (methodDef.Body == null) { return null; } context.CancellationToken.ThrowIfCancellationRequested(); ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); ilMethod.Body = astBuilder.Build(methodDef, true, context); context.CancellationToken.ThrowIfCancellationRequested(); ILAstOptimizer bodyGraph = new ILAstOptimizer(); bodyGraph.Optimize(context, ilMethod); context.CancellationToken.ThrowIfCancellationRequested(); var localVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable) .Where(v => v != null && !v.IsParameter).Distinct(); Debug.Assert(context.CurrentMethod == methodDef); NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, localVariables, ilMethod); if (parameters != null) { foreach (var pair in (from p in parameters join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter select new { p, v.Name })) { pair.p.Name = pair.Name; } } context.CancellationToken.ThrowIfCancellationRequested(); Ast.BlockStatement astBlock = TransformBlock(ilMethod); CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments Statement insertionPoint = astBlock.Statements.FirstOrDefault(); foreach (ILVariable v in localVariablesToDefine) { AstType type; if (v.Type.ContainsAnonymousType()) type = new SimpleType("var"); else type = AstBuilder.ConvertType(v.Type); var newVarDecl = new VariableDeclarationStatement(type, v.Name); newVarDecl.Variables.Single().AddAnnotation(v); astBlock.Statements.InsertBefore(insertionPoint, newVarDecl); } astBlock.AddAnnotation(new MemberMapping(methodDef) { LocalVariables = localVariables }); return astBlock; }