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 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)
|| !(flow.lastModified.outer instanceof SequentialBlock))
return false;
@ -38,64 +57,70 @@ public class CreateNewConstructor implements Transformation{
return false;
/* The rest should probably succeed */
int params = constrCall.getOperandCount();
Expression[] exprs = new Expression[params];
int params = constrCall.getOperandCount() - 1;
SpecialBlock optDup = null;
SequentialBlock sequBlock = (SequentialBlock) block.outer;
try {
for_loop:
for (int i = params-1; i>0; i--) {
block = (InstructionBlock) sequBlock.subBlocks[0];
exprs[i] = block.getInstruction();
sequBlock = (SequentialBlock) sequBlock.outer;
while (sequBlock.subBlocks[0] instanceof InstructionBlock) {
Expression expr =
((InstructionBlock) sequBlock.subBlocks[0])
.getInstruction();
if (!expr.isVoid())
continue for_loop;
if (exprs[i].canCombine(expr) <= 0)
while (params > 0) {
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock))
return false;
Expression expr
= ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
if (!expr.isVoid())
params--;
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;
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;
}
params = optDup.count;
} else
return false;
}
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];
if (dup.type != SpecialBlock.DUP
|| dup.count != 1 || dup.depth != 0)
return false;
sequBlock = (SequentialBlock)sequBlock.outer;
if (!(sequBlock.subBlocks[0] instanceof InstructionBlock))
return false;
block = (InstructionBlock) sequBlock.subBlocks[0];
exprs[0] = block.getInstruction();
if (exprs[0].isVoid())
if (!(block.getInstruction() instanceof NewOperator))
return false;
NewOperator op = (NewOperator) exprs[0].getOperator();
NewOperator op = (NewOperator) block.getInstruction();
if (constrCall.getClassType() != op.getType())
return false;
} catch (ClassCastException ex) {
return false;
} catch (NullPointerException ex) {
return false;
block.removeBlock();
dup.removeBlock();
if (optDup != null)
optDup.depth = 0;
((InstructionContainer) flow.lastModified).setInstruction
(new ConstructorOperator(constrCall.getClassType(),
constrCall.getMethodType()));
return true;
}
((InstructionContainer) flow.lastModified).setInstruction
(new ComplexExpression
(new ConstructorOperator(constrCall.getClassType(),
constrCall.getField()),
exprs));
flow.lastModified.moveDefinitions(sequBlock, null);
flow.lastModified.replace(sequBlock);
return true;
return false;
}
}

Loading…
Cancel
Save