|
|
@ -44,120 +44,56 @@ public class CreateExpression { |
|
|
|
if (params == 0) |
|
|
|
if (params == 0) |
|
|
|
return false; |
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(last.outer instanceof SequentialBlock)) |
|
|
|
if (!(last.outer instanceof SequentialBlock)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
SequentialBlock sequBlock = (SequentialBlock)last.outer; |
|
|
|
SequentialBlock sequBlock = (SequentialBlock)last.outer; |
|
|
|
|
|
|
|
|
|
|
|
/* First check if Expression can be created, but do nothing yet. |
|
|
|
/* First check if Expression can be created, but do nothing yet. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Expression lastExpression = null; |
|
|
|
Expression lastExpression = ic.getInstruction(); |
|
|
|
for (int i = params;;) { |
|
|
|
while (true) { |
|
|
|
|
|
|
|
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (i >= 2 && sequBlock.subBlocks[0] instanceof SpecialBlock) { |
|
|
|
Expression expr = |
|
|
|
/* Transform (this is for string += under jikes) |
|
|
|
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); |
|
|
|
* PUSH arg2 |
|
|
|
|
|
|
|
* PUSH arg1 |
|
|
|
|
|
|
|
* SWAP |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
SpecialBlock swap = (SpecialBlock) sequBlock.subBlocks[0]; |
|
|
|
|
|
|
|
if (swap.type != SpecialBlock.SWAP) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
/* XXX check if swapping is possible */ |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|| !(expr.getOperator() |
|
|
|
|
|
|
|
instanceof CombineableOperator) |
|
|
|
|
|
|
|
|| 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 (!expr.isVoid()) |
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (expr.getOperandCount() > 0 |
|
|
|
|
|
|
|
|| !(expr.getOperator() instanceof CombineableOperator) |
|
|
|
|
|
|
|
|| lastExpression.canCombine(expr) <= 0) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastExpression = expr; |
|
|
|
if (!(sequBlock.outer instanceof SequentialBlock)) |
|
|
|
if (!(sequBlock.outer instanceof SequentialBlock)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
sequBlock = (SequentialBlock) sequBlock.outer; |
|
|
|
sequBlock = (SequentialBlock) sequBlock.outer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Now, do the combination. Everything must succeed now. |
|
|
|
/* Now, do the combination. Everything must succeed now. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Expression[] exprs = new Expression[params]; |
|
|
|
|
|
|
|
sequBlock = (SequentialBlock) last.outer; |
|
|
|
sequBlock = (SequentialBlock) last.outer; |
|
|
|
int swapping = 0; |
|
|
|
lastExpression = ic.getInstruction(); |
|
|
|
for (int i=params; ;) { |
|
|
|
while (true) { |
|
|
|
|
|
|
|
|
|
|
|
if (sequBlock.subBlocks[0] instanceof SpecialBlock) { |
|
|
|
Expression expr = |
|
|
|
// This must be a swap (see above).
|
|
|
|
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); |
|
|
|
swapping = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (!expr.isVoid()) { |
|
|
|
} else { |
|
|
|
lastExpression = lastExpression.addOperand(expr); |
|
|
|
Expression expr = |
|
|
|
break; |
|
|
|
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!expr.isVoid()) { |
|
|
|
|
|
|
|
if (swapping == 1) { |
|
|
|
|
|
|
|
// We start swapping:
|
|
|
|
|
|
|
|
i--; |
|
|
|
|
|
|
|
swapping = 2; |
|
|
|
|
|
|
|
} else if (swapping == 2) { |
|
|
|
|
|
|
|
// We continue swapping:
|
|
|
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
swapping = 3; |
|
|
|
|
|
|
|
} else if (swapping == 3) { |
|
|
|
|
|
|
|
// Now we end swapping:
|
|
|
|
|
|
|
|
i--; |
|
|
|
|
|
|
|
swapping = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
exprs[--i] = expr; |
|
|
|
|
|
|
|
if (i == 0 && swapping == 0 |
|
|
|
|
|
|
|
|| i == 1 && swapping == 3) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
exprs[i] = exprs[i].combine(expr); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastExpression = lastExpression.combine(expr); |
|
|
|
sequBlock = (SequentialBlock)sequBlock.outer; |
|
|
|
sequBlock = (SequentialBlock)sequBlock.outer; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(Decompiler.isVerbose) |
|
|
|
if(Decompiler.isVerbose && lastExpression.getOperandCount() == 0) |
|
|
|
Decompiler.err.print('x'); |
|
|
|
Decompiler.err.print('x'); |
|
|
|
|
|
|
|
|
|
|
|
Expression newExpr; |
|
|
|
ic.setInstruction(lastExpression); |
|
|
|
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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ic.moveDefinitions(sequBlock, last); |
|
|
|
ic.moveDefinitions(sequBlock, last); |
|
|
|
last.replace(sequBlock); |
|
|
|
last.replace(sequBlock); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|