From a90bc23dea71e31496e2e7202a3b48590f6a7060 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 5 Feb 1999 12:52:15 +0000 Subject: [PATCH] This will one time mark inlined expression, to allow further handling. this doesn't even compile yet git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@184 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/MarkInlineExpression.java | 139 ++++++++++------------- 1 file changed, 58 insertions(+), 81 deletions(-) diff --git a/jode/jode/flow/MarkInlineExpression.java b/jode/jode/flow/MarkInlineExpression.java index b89976d..8397295 100644 --- a/jode/jode/flow/MarkInlineExpression.java +++ b/jode/jode/flow/MarkInlineExpression.java @@ -27,15 +27,29 @@ import jode.decompiler.*; * The parameters may be stored in locals, before inlining the body of the * method. * - * This transformation will mark the expression as inlined and - * This transformation creates expressions. It transforms - *
- *  Sequ[expr_1, Sequ[expr_2, ..., Sequ[expr_n, op] ...]] 
- * 
- * to - *
- *  expr(op, [ expr_1, ..., expr_n ])
- * 
+ * Inlined methods look as follows: + * + * local_1 = expr_1 + * local_2 = expr_2 + * [PUSH ]expr(local_1,local_2,constants...) + * + * where local_1 and local_2 aren't used any more. + * + * If later one finds a reuse of local_x, the inline transformation + * must be reverted: If there is no surrounding expression, the locals + * are moved to initializers around; otherwise if the locals are used + * in the expression or a super expression, they are combined with the + * next occurence; otherwise the locals are moved behind the next expression. + * This doesn't care for side effects though :-( + * + * There are many other reasons why a part could look like this; only + * if a matching method is found, that does exactly this (or if the + * options createInlines is given), we may call this method. + * + * As long as inlines are not supported, if the local is never used, it + * is simply removed; if the local is used only one time and there are + * no side effects to the expression on the right hand side between usage + * and initialization, the usage is replaced by the right hand side. */ public class MarkInlineExpression { @@ -52,88 +66,51 @@ public class MarkInlineExpression { return false; ComplexExpression parent = null; - Expression inner = ic.getInstruction(); - while (inner instanceof ComplexExpression) { - parent = (ComplexExpression)inner; - inner = parent.getSubExpressions()[0]; - } - - if (!(inner instanceof Operator)) - return false; - - Operator op = (Operator)inner; + Expression expr = ic.getInstruction(); if (!(last.outer instanceof SequentialBlock)) return false; SequentialBlock sequBlock = (SequentialBlock)last.outer; - /* First check if Expression can be created, but do nothing yet. - */ - Expression lastExpression = null; - for (int i = params;;) { - - if (!(sequBlock.subBlocks[0] instanceof InstructionBlock)) - return false; - - Expression expr = - ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); - - - if (!expr.isVoid()) { - if (--i == 0) - break; - } else if (lastExpression == null - || lastExpression.canCombine(expr) <= 0) - return false; - - if (expr.getOperandCount() > 0) - /* This is a not fully resolved expression in the - * middle, we must not touch it. */ - return false; - - lastExpression = expr; - - if (!(sequBlock.outer instanceof SequentialBlock)) - return false; - sequBlock = (SequentialBlock) sequBlock.outer; + int localCount = 0; + while (sequBlock.subBlocks[0] instanceof InstructionBlock) { + InstructionBlock assign = + (InstructionBlock) sequBlock.subBlocks[0]; + if (!(assign.getInstruction().getOperator() + instanceof LocalStoreOperator) + || assign.getInstruction().getOperandCount() == 0) + break; + + LocalStoreOperator store = (LocalStoreOperator) + assign.getInstruction().getOperator(); + if (!store.getLocal().onlyUsedInside(expr)) + break; + + localCount++; + + if (!(sequBlock.outer instanceof SequentialBlock)) + break; + sequBlock = (SequentialBlock)sequBlock.outer; } + if (localCount == 0) + return false; - /* Now, do the combination. Everything must succeed now. - */ - Expression[] exprs = new Expression[params]; + Expression[] stores = new Expression[localCount]; sequBlock = (SequentialBlock) last.outer; - for (int i=params; ;) { - - Expression expr = - ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); - - if (!expr.isVoid()) { - exprs[--i] = expr; - if (i == 0) - break; - } else - exprs[i] = exprs[i].combine(expr); - - sequBlock = (SequentialBlock)sequBlock.outer; - } - - if(Decompiler.isVerbose) - Decompiler.err.print('x'); - - Expression newExpr; - if (params == 1 && op instanceof NopOperator) { - exprs[0].setType(op.getType()); - newExpr = exprs[0]; - } else - newExpr = new ComplexExpression(op, exprs); - - if (parent != null) - parent.setSubExpressions(0, newExpr); - else - ic.setInstruction(newExpr); - + for (int i=0; i