simplified. Rest is done in CreateExpression

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@93 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent c25af54827
commit cbfb4fb801
  1. 117
      jode/jode/flow/CreateNewConstructor.java

@ -27,6 +27,25 @@ import jode.NewOperator;
public class CreateNewConstructor implements Transformation{ public class CreateNewConstructor implements Transformation{
public boolean transform(FlowBlock flow) { public boolean transform(FlowBlock flow) {
/* Situation:
*
* new <object>
* DUP
* PUSH load_ops
* optionally: <= used for "string1 += string2"
* DUP_X2
* [ n non void + some void expressions ]
* stack_n.<init>(stack_n-1,...,stack_0)
*
* transform it to
*
* PUSH load_ops
* optionally:
* DUP_X1 <= remove the depth
* [ n non void + some void expressions ]
* PUSH new <object>(stack_n-1,...,stack_0)
*/
if (!(flow.lastModified instanceof InstructionBlock) if (!(flow.lastModified instanceof InstructionBlock)
|| !(flow.lastModified.outer instanceof SequentialBlock)) || !(flow.lastModified.outer instanceof SequentialBlock))
return false; return false;
@ -38,64 +57,70 @@ public class CreateNewConstructor implements Transformation{
return false; return false;
/* The rest should probably succeed */ /* The rest should probably succeed */
int params = constrCall.getOperandCount(); int params = constrCall.getOperandCount() - 1;
Expression[] exprs = new Expression[params]; SpecialBlock optDup = null;
SequentialBlock sequBlock = (SequentialBlock) block.outer; SequentialBlock sequBlock = (SequentialBlock) block.outer;
try { while (params > 0) {
for_loop: if (!(sequBlock.subBlocks[0] instanceof InstructionBlock))
for (int i = params-1; i>0; i--) { return false;
Expression expr
block = (InstructionBlock) sequBlock.subBlocks[0]; = ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
exprs[i] = block.getInstruction(); if (!expr.isVoid())
sequBlock = (SequentialBlock) sequBlock.outer; params--;
if (expr.getOperandCount() > 0) {
while (sequBlock.subBlocks[0] instanceof InstructionBlock) { if (params == 0
&& sequBlock.outer instanceof SequentialBlock
Expression expr = && sequBlock.outer.getSubBlocks()[0]
((InstructionBlock) sequBlock.subBlocks[0]) instanceof SpecialBlock) {
.getInstruction(); /* handle the optional dup */
sequBlock = (SequentialBlock) sequBlock.outer;
if (!expr.isVoid()) optDup = (SpecialBlock) sequBlock.subBlocks[0];
continue for_loop; if (optDup.type != SpecialBlock.DUP
if (exprs[i].canCombine(expr) <= 0) || optDup.depth != 2)
return false; return false;
params = optDup.count;
exprs[i] = exprs[i].combine(expr); } else
SequentialBlock subExprBlock = return false;
(SequentialBlock) sequBlock.subBlocks[1];
subExprBlock.moveDefinitions(sequBlock, subExprBlock);
subExprBlock.replace(sequBlock);
sequBlock = subExprBlock;
((InstructionContainer)subExprBlock.subBlocks[0]).
setInstruction(exprs[i]);
sequBlock = (SequentialBlock)sequBlock.outer;
}
} }
if (!(sequBlock.outer instanceof SequentialBlock))
return false;
sequBlock = (SequentialBlock) sequBlock.outer;
}
while (sequBlock.subBlocks[0] instanceof InstructionBlock
&& ((InstructionBlock)sequBlock.subBlocks[0])
.getInstruction().isVoid()
&& sequBlock.outer instanceof SequentialBlock)
sequBlock = (SequentialBlock) sequBlock.outer;
if (sequBlock.outer instanceof SequentialBlock
&& sequBlock.subBlocks[0] instanceof SpecialBlock) {
SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0]; SpecialBlock dup = (SpecialBlock) sequBlock.subBlocks[0];
if (dup.type != SpecialBlock.DUP if (dup.type != SpecialBlock.DUP
|| dup.count != 1 || dup.depth != 0) || dup.count != 1 || dup.depth != 0)
return false; return false;
sequBlock = (SequentialBlock)sequBlock.outer; sequBlock = (SequentialBlock)sequBlock.outer;
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock))
return false;
block = (InstructionBlock) sequBlock.subBlocks[0]; block = (InstructionBlock) sequBlock.subBlocks[0];
exprs[0] = block.getInstruction(); if (!(block.getInstruction() instanceof NewOperator))
if (exprs[0].isVoid())
return false; return false;
NewOperator op = (NewOperator) exprs[0].getOperator();
NewOperator op = (NewOperator) block.getInstruction();
if (constrCall.getClassType() != op.getType()) if (constrCall.getClassType() != op.getType())
return false; return false;
} catch (ClassCastException ex) {
return false;
} catch (NullPointerException ex) {
return false;
}
((InstructionContainer) flow.lastModified).setInstruction
(new ComplexExpression
(new ConstructorOperator(constrCall.getClassType(),
constrCall.getField()),
exprs));
flow.lastModified.moveDefinitions(sequBlock, null); block.removeBlock();
flow.lastModified.replace(sequBlock); dup.removeBlock();
return true; if (optDup != null)
optDup.depth = 0;
((InstructionContainer) flow.lastModified).setInstruction
(new ConstructorOperator(constrCall.getClassType(),
constrCall.getMethodType()));
return true;
}
return false;
} }
} }

Loading…
Cancel
Save