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
stable
jochen 26 years ago
parent e81fefddfd
commit a90bc23dea
  1. 139
      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
* <pre>
* Sequ[expr_1, Sequ[expr_2, ..., Sequ[expr_n, op] ...]]
* </pre>
* to
* <pre>
* expr(op, [ expr_1, ..., expr_n ])
* </pre>
* 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<stores; i++) {
stores[i] = ((InstructionBlock)sequBlock.subBlocks[0])
.getInstruction();
LocalStoreOperator store =
(LocalStoreOperator) stores[i].getOperator();
if (!store.getLocal().onlyUsedInside(expr))
stores[i].get.markInlinedIn(expr);
sequBlock = (SequentialBlock)sequBlock.outer;
}
expr.markInlineExpression(stores);
ic.moveDefinitions(sequBlock, last);
last.replace(sequBlock);
return true;
}
}

Loading…
Cancel
Save