From acdac3ecf5d82b4bbd20819b5eec3d287ff6d5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Mon, 12 Nov 2007 01:01:29 +0000 Subject: [PATCH] Join consecutive expression together if possible --- src/AstMetodBodyBuilder.cs | 5 +++-- src/StackExpression.cs | 17 +++++++++++++++++ src/StackExpressionCollection.cs | 14 +++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index 7bda9a6e3..37c9609bd 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -20,6 +20,7 @@ namespace Decompiler ByteCodeCollection body = new ByteCodeCollection(methodDef); StackExpressionCollection exprCol = new StackExpressionCollection(body); + exprCol.Optimize(); foreach(VariableDefinition varDef in methodDef.Body.Variables) { Ast.VariableDeclaration astVar = new Ast.VariableDeclaration(varDef.Name); @@ -73,11 +74,11 @@ namespace Decompiler List allArgs = new List(); // Add args from stack allArgs.AddRange(args); - // Args generated by nested expressions + // Args generated by nested expressions (which must be closed) foreach(StackExpression nestedExpr in expr.LastArguments) { allArgs.Add(new Ast.ParenthesizedExpression((Ast.Expression)MakeCodeDomExpression(methodDef, nestedExpr))); } - return MakeCodeDomExpression(methodDef, expr.ExpressionByteCode, args); + return MakeCodeDomExpression(methodDef, expr.ExpressionByteCode, allArgs.ToArray()); } static object MakeCodeDomExpression(MethodDefinition methodDef, ByteCode byteCode, params Ast.Expression[] args) diff --git a/src/StackExpression.cs b/src/StackExpression.cs index 59714bfdf..c2f7d20bc 100644 --- a/src/StackExpression.cs +++ b/src/StackExpression.cs @@ -16,6 +16,7 @@ namespace Decompiler get { return expressionByteCode; } } + // A list of closed expression for last arguments public List LastArguments { get { return lastArguments; } } @@ -32,6 +33,22 @@ namespace Decompiler } } + /// + /// Expression is closed if it has no inputs and has exactly one output + /// + public bool IsClosed { + get { + return this.PopCount == 0 && + this.PushCount == 1; + } + } + + public bool IsBranchTarget { + get { + return this.FirstByteCode.BranchesHere.Count > 0; + } + } + public int PopCount { get { int popCount; diff --git a/src/StackExpressionCollection.cs b/src/StackExpressionCollection.cs index 81beb2a81..4c299574e 100644 --- a/src/StackExpressionCollection.cs +++ b/src/StackExpressionCollection.cs @@ -18,7 +18,19 @@ namespace Decompiler public void Optimize() { - + for(int i = 1; i < this.Count; i++) { + StackExpression prevExpr = this[i - 1]; + StackExpression expr = this[i]; + + if (expr.PopCount > 0 && // This expr needs some more arguments + !expr.IsBranchTarget && + prevExpr.IsClosed) + { + this.RemoveAt(i - 1); i--; + expr.LastArguments.Insert(0, prevExpr); + i--; + } + } } } }