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. 109
      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();
sequBlock = (SequentialBlock) sequBlock.outer;
while (sequBlock.subBlocks[0] instanceof InstructionBlock) {
Expression expr =
((InstructionBlock) sequBlock.subBlocks[0])
.getInstruction();
if (!expr.isVoid()) if (!expr.isVoid())
continue for_loop; params--;
if (exprs[i].canCombine(expr) <= 0) if (expr.getOperandCount() > 0) {
if (params == 0
&& sequBlock.outer instanceof SequentialBlock
&& sequBlock.outer.getSubBlocks()[0]
instanceof SpecialBlock) {
/* handle the optional dup */
sequBlock = (SequentialBlock) sequBlock.outer;
optDup = (SpecialBlock) sequBlock.subBlocks[0];
if (optDup.type != SpecialBlock.DUP
|| optDup.depth != 2)
return false;
params = optDup.count;
} else
return false; return false;
exprs[i] = exprs[i].combine(expr);
SequentialBlock subExprBlock =
(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; block.removeBlock();
} catch (NullPointerException ex) { dup.removeBlock();
return false; if (optDup != null)
} optDup.depth = 0;
((InstructionContainer) flow.lastModified).setInstruction ((InstructionContainer) flow.lastModified).setInstruction
(new ComplexExpression
(new ConstructorOperator(constrCall.getClassType(), (new ConstructorOperator(constrCall.getClassType(),
constrCall.getField()), constrCall.getMethodType()));
exprs));
flow.lastModified.moveDefinitions(sequBlock, null);
flow.lastModified.replace(sequBlock);
return true; return true;
} }
return false;
}
} }

Loading…
Cancel
Save