*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@109 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 230ad289d5
commit df4c4560bb
  1. 10
      jode/jode/flow/CreateForInitializer.java
  2. 231
      jode/jode/flow/FlowBlock.java
  3. 91
      jode/jode/flow/LoopBlock.java
  4. 6
      jode/jode/flow/SequentialBlock.java
  5. 8
      jode/jode/flow/StructuredBlock.java
  6. 20
      jode/jode/flow/VariableSet.java

@ -41,16 +41,16 @@ public class CreateForInitializer {
Expression initializer = Expression initializer =
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction(); ((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
if (!(initializer.getOperator() instanceof StoreInstruction) if (!initializer.getOperator().isVoid()
|| !initializer.getOperator().isVoid()) || (forBlock.cond != forBlock.TRUE
&& !forBlock.cond.containsMatchingLoad(initializer)))
return false; return false;
if (jode.Decompiler.isVerbose) if (jode.Decompiler.isVerbose)
System.err.print('f'); System.err.print('f');
forBlock.init = initializer; forBlock.init = (InstructionBlock) sequBlock.subBlocks[0];
forBlock.moveDefinitions(last.outer, null); last.replace(sequBlock);
last.replace(last.outer);
return true; return true;
} }
} }

@ -198,70 +198,75 @@ public class FlowBlock {
ConditionalBlock cb = (ConditionalBlock) jump.prev.outer; ConditionalBlock cb = (ConditionalBlock) jump.prev.outer;
Expression instr = cb.getInstruction(); Expression instr = cb.getInstruction();
/* If this is the first instruction of a
* while/for(true) block, make this the loop condition
* (negated of course).
*/
// if (cb.outer instanceof LoopBlock if (cb.outer instanceof LoopBlock
// || (cb.outer instanceof SequentialBlock || (cb.outer instanceof SequentialBlock
// && cb.outer.getSubBlocks()[0] == cb && cb.outer.getSubBlocks()[0] == cb
// && cb.outer.outer instanceof LoopBlock)) { && cb.outer.outer instanceof LoopBlock)) {
// LoopBlock loopBlock = (cb.outer instanceof LoopBlock) ? LoopBlock loopBlock = (cb.outer instanceof LoopBlock) ?
// (LoopBlock) cb.outer : (LoopBlock) cb.outer.outer; (LoopBlock) cb.outer : (LoopBlock) cb.outer.outer;
// if (loopBlock.getCondition() == LoopBlock.TRUE && if (loopBlock.getCondition() == LoopBlock.TRUE &&
// loopBlock.getType() != LoopBlock.DOWHILE && loopBlock.getType() != LoopBlock.DOWHILE &&
// (loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
// || loopBlock.getNextFlowBlock() == succ)) { || loopBlock.getNextFlowBlock() == succ)) {
// if (loopBlock.jump == null) { if (loopBlock.jump == null) {
// /* consider this jump again */ /* consider this jump again */
// loopBlock.moveJump(jump); loopBlock.moveJump(jump);
// jumps = jump; jumps = jump;
// } else } else
// jump.prev.removeJump(); jump.prev.removeJump();
// loopBlock.setCondition(instr.negate()); loopBlock.setCondition(instr.negate());
// loopBlock.moveDefinitions(cb, null); loopBlock.moveDefinitions(cb, null);
// cb.removeBlock(); cb.removeBlock();
// continue; continue;
// } }
// } else if (cb.outer instanceof SequentialBlock } else if (cb.outer instanceof SequentialBlock
// && cb.outer.getSubBlocks()[1] == cb) { && cb.outer.getSubBlocks()[1] == cb) {
// /* And now for do/while loops, where the jump is /* And now for do/while loops, where the jump is
// * at the end of the loop. * at the end of the loop.
// */ */
// /* First find the beginning of the loop */ /* First find the beginning of the loop */
// StructuredBlock sb = cb.outer.outer; StructuredBlock sb = cb.outer.outer;
// while (sb instanceof SequentialBlock) { while (sb instanceof SequentialBlock) {
// sb = sb.outer; sb = sb.outer;
// } }
// /* sb is now the first and cb is the last /* sb is now the first and cb is the last
// * instruction in the current block. * instruction in the current block.
// */ */
// if (sb instanceof LoopBlock) { if (sb instanceof LoopBlock) {
// LoopBlock loopBlock = (LoopBlock) sb; LoopBlock loopBlock = (LoopBlock) sb;
// if (loopBlock.getCondition() == LoopBlock.TRUE && if (loopBlock.getCondition() == LoopBlock.TRUE &&
// loopBlock.getType() == LoopBlock.WHILE && loopBlock.getType() == LoopBlock.WHILE &&
// (loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
// || loopBlock.getNextFlowBlock() == succ)) { || loopBlock.getNextFlowBlock() == succ)) {
// if (loopBlock.jump == null) { if (loopBlock.jump == null) {
// /* consider this jump again */ /* consider this jump again */
// loopBlock.moveJump(jump); loopBlock.moveJump(jump);
// jumps = jump; jumps = jump;
// } else } else
// jump.prev.removeJump(); jump.prev.removeJump();
// loopBlock.setType(LoopBlock.DOWHILE); loopBlock.setType(LoopBlock.DOWHILE);
// loopBlock.setCondition(instr.negate()); loopBlock.setCondition(instr.negate());
// loopBlock.moveDefinitions(cb, null); loopBlock.moveDefinitions(cb, null);
// cb.removeBlock(); cb.removeBlock();
// continue; continue;
// } }
// } }
// } }
/* replace all conditional jumps to the successor, which /* replace all conditional jumps to the successor, which
* are followed by a block which has the end of the block * are followed by a block which has the end of the block
@ -669,44 +674,44 @@ public class FlowBlock {
return true; return true;
} }
/** // /**
* Find the exit condition of a for/while block. The loop block // * Find the exit condition of a for/while block. The loop block
* mustn't have an exit condition yet. // * mustn't have an exit condition yet.
*/ // */
public void mergeCondition() { // public void mergeCondition() {
/* If the first instruction of a while is a conditional // /* If the first instruction of a while is a conditional
* block, which jumps to the next address use the condition // * block, which jumps to the next address use the condition
* as while condition. // * as while condition.
*/ // */
LoopBlock loopBlock = (LoopBlock) lastModified; // LoopBlock loopBlock = (LoopBlock) lastModified;
int loopType = loopBlock.getType(); // int loopType = loopBlock.getType();
ConditionalBlock cb = null; // ConditionalBlock cb = null;
if (loopBlock.bodyBlock instanceof ConditionalBlock) // if (loopBlock.bodyBlock instanceof ConditionalBlock)
cb = (ConditionalBlock) loopBlock.bodyBlock; // cb = (ConditionalBlock) loopBlock.bodyBlock;
else if (loopBlock.bodyBlock instanceof SequentialBlock // else if (loopBlock.bodyBlock instanceof SequentialBlock
&& loopBlock.bodyBlock.getSubBlocks()[0] // && loopBlock.bodyBlock.getSubBlocks()[0]
instanceof ConditionalBlock) // instanceof ConditionalBlock)
cb = (ConditionalBlock) loopBlock.bodyBlock.getSubBlocks()[0]; // cb = (ConditionalBlock) loopBlock.bodyBlock.getSubBlocks()[0];
else if (loopBlock.bodyBlock instanceof SequentialBlock // else if (loopBlock.bodyBlock instanceof SequentialBlock
&& loopType == LoopBlock.WHILE) { // && loopType == LoopBlock.WHILE) {
loopType = LoopBlock.DOWHILE; // loopType = LoopBlock.DOWHILE;
SequentialBlock sequBlock = (SequentialBlock) loopBlock.bodyBlock; // SequentialBlock sequBlock = (SequentialBlock) loopBlock.bodyBlock;
while (sequBlock.subBlocks[1] instanceof SequentialBlock) // while (sequBlock.subBlocks[1] instanceof SequentialBlock)
sequBlock = (SequentialBlock) sequBlock.subBlocks[1]; // sequBlock = (SequentialBlock) sequBlock.subBlocks[1];
if (sequBlock.subBlocks[1] instanceof ConditionalBlock) // if (sequBlock.subBlocks[1] instanceof ConditionalBlock)
cb = (ConditionalBlock) sequBlock.subBlocks[1]; // cb = (ConditionalBlock) sequBlock.subBlocks[1];
} // }
if (cb != null // if (cb != null
&& cb.trueBlock.jump.destination.addr == addr + length) { // && cb.trueBlock.jump.destination.addr == addr + length) {
loopBlock.moveJump(cb.trueBlock.jump); // loopBlock.moveJump(cb.trueBlock.jump);
loopBlock.setCondition(cb.getInstruction().negate()); // loopBlock.setCondition(cb.getInstruction().negate());
loopBlock.setType(loopType); // loopBlock.setType(loopType);
loopBlock.moveDefinitions(cb, null); // loopBlock.moveDefinitions(cb, null);
cb.removeBlock(); // cb.removeBlock();
} // }
} // }
public boolean doT2(int start, int end) { public boolean doT2(int start, int end) {
/* If there are no jumps to the beginning of this flow block /* If there are no jumps to the beginning of this flow block
@ -749,8 +754,6 @@ public class FlowBlock {
&& lastModified instanceof InstructionBlock && lastModified instanceof InstructionBlock
&& ((InstructionBlock)lastModified).getInstruction().isVoid()) { && ((InstructionBlock)lastModified).getInstruction().isVoid()) {
Expression instr =
((InstructionBlock)lastModified).getInstruction();
if (lastModified.outer instanceof SequentialBlock if (lastModified.outer instanceof SequentialBlock
&& lastModified.outer.getSubBlocks()[0] && lastModified.outer.getSubBlocks()[0]
instanceof LoopBlock) { instanceof LoopBlock) {
@ -767,38 +770,40 @@ public class FlowBlock {
* continue to for. * continue to for.
*/ */
lastModified.removeJump();
LoopBlock forBlock = LoopBlock forBlock =
new LoopBlock(LoopBlock.FOR, LoopBlock.TRUE); new LoopBlock(LoopBlock.FOR, LoopBlock.TRUE);
forBlock.replace(bodyBlock); forBlock.replace(bodyBlock);
forBlock.setBody(bodyBlock); forBlock.setBody(bodyBlock);
forBlock.incr = instr; forBlock.incr = (InstructionBlock) lastModified;
forBlock.moveDefinitions(lastModified, null);
forBlock.replaceBreakContinue(lb); forBlock.replaceBreakContinue(lb);
lastModified.removeJump();
lb.bodyBlock.replace(lastModified.outer); lb.bodyBlock.replace(lastModified.outer);
createdForBlock = true; createdForBlock = true;
} }
} }
if (!createdForBlock && if (!createdForBlock
(instr.getOperator() instanceof StoreInstruction && ((InstructionBlock)
|| instr.getOperator() instanceof IIncOperator)) { lastModified).getInstruction().isVoid()) {
/* The only jump is the jump of the last /* The only jump is the jump of the last
* instruction lastModified */ * instruction lastModified, there is a big
* chance, that this is a for block, but we
* can't be sure until we have seen the condition.
* We will transform it to a for block, and take
* that back, when we get a non matching condition.
*/
lastModified.removeJump();
LoopBlock forBlock = LoopBlock forBlock =
new LoopBlock(LoopBlock.FOR, LoopBlock.TRUE); new LoopBlock(LoopBlock.POSSFOR, LoopBlock.TRUE);
forBlock.replace(bodyBlock); forBlock.replace(bodyBlock);
forBlock.setBody(bodyBlock); forBlock.setBody(bodyBlock);
forBlock.incr = instr; forBlock.incr = (InstructionBlock) lastModified;
forBlock.moveDefinitions(lastModified, null); lastModified.removeBlock();
lastModified.removeJump();
lastModified.outer.getSubBlocks()[0]
.replace(lastModified.outer);
createdForBlock = true; createdForBlock = true;
} }
} }
@ -864,7 +869,8 @@ public class FlowBlock {
*/ */
predecessors.removeElement(this); predecessors.removeElement(this);
lastModified = block; lastModified = block;
mergeCondition(); doTransformations();
// mergeCondition();
/* T2 analysis succeeded */ /* T2 analysis succeeded */
checkConsistent(); checkConsistent();
@ -942,6 +948,7 @@ public class FlowBlock {
if (lastModified.jump.destination == END_OF_METHOD) if (lastModified.jump.destination == END_OF_METHOD)
lastModified.removeJump(); lastModified.removeJump();
doTransformations();
/* transformation succeeded */ /* transformation succeeded */
checkConsistent(); checkConsistent();
} }

@ -33,6 +33,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public static final int WHILE = 0; public static final int WHILE = 0;
public static final int DOWHILE = 1; public static final int DOWHILE = 1;
public static final int FOR = 2; public static final int FOR = 2;
public static final int POSSFOR = 3;
public static final Expression TRUE = public static final Expression TRUE =
new ConstOperator(Type.tBoolean, "1"); new ConstOperator(Type.tBoolean, "1");
@ -44,13 +45,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
*/ */
Expression cond; Expression cond;
/** /**
* The init instruction, only valid if type == FOR. * The init instruction, only valid if type == FOR or POSSFOR
*/ */
Expression init; InstructionBlock init;
/** /**
* The increase instruction, only valid if type == FOR. * The increase instruction, only valid if type == FOR or POSSFOR.
*/ */
Expression incr; InstructionBlock incr;
/** /**
* True, if the initializer is a declaration. * True, if the initializer is a declaration.
@ -98,8 +99,43 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
return cond; return cond;
} }
public void putBackInit() {
StructuredBlock last =
(outer instanceof SequentialBlock
&& outer.getSubBlocks()[0] == this) ? outer : this;
SequentialBlock sequBlock = new SequentialBlock();
sequBlock.replace(last);
sequBlock.setFirst(init);
sequBlock.setSecond(last);
init = null;
}
public void setCondition(Expression cond) { public void setCondition(Expression cond) {
this.cond = cond; this.cond = cond;
if (type == POSSFOR) {
/* canCombine returns 1 if cond contains a sub expression
* that matches the store in incr */
if (cond.containsMatchingLoad(incr.getInstruction())) {
type = FOR;
if (init != null
&& !cond.containsMatchingLoad(init.getInstruction())) {
/* This is a for, but the init instruction doesn't
* match. Put the init back to its old place.
*/
putBackInit();
}
} else {
type = WHILE;
StructuredBlock last = bodyBlock;
while (last instanceof SequentialBlock)
last = last.getSubBlocks()[1];
last.appendBlock(incr);
incr = null;
if (init != null)
putBackInit();
}
}
mayChangeJump = false; mayChangeJump = false;
} }
@ -111,6 +147,16 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
this.type = type; this.type = type;
} }
public VariableSet propagateUsage() {
if (init != null)
used.unionExact(init.used);
if (incr != null)
used.unionExact(incr.used);
VariableSet allUse = (VariableSet) used.clone();
allUse.unionExact(bodyBlock.propagateUsage());
return allUse;
}
/** /**
* Replaces the given sub block with a new block. * Replaces the given sub block with a new block.
* @param oldBlock the old sub block. * @param oldBlock the old sub block.
@ -136,11 +182,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public void dumpDeclaration(TabbedPrintWriter writer, LocalInfo local) public void dumpDeclaration(TabbedPrintWriter writer, LocalInfo local)
throws java.io.IOException throws java.io.IOException
{ {
if (type == FOR && init != null if ((type == FOR || type == POSSFOR) && init != null
&& (outer == null || !outer.used.contains(local)) && (outer == null || !outer.used.contains(local))
&& init.getOperator() instanceof LocalStoreOperator && (init.getInstruction().getOperator()
&& ((LocalStoreOperator) init.getOperator()).getLocalInfo() instanceof LocalStoreOperator)
== local.getLocalInfo()) && (((LocalStoreOperator)
init.getInstruction().getOperator()).getLocalInfo()
== local.getLocalInfo()))
isDeclaration = true; isDeclaration = true;
else else
super.dumpDeclaration(writer, local); super.dumpDeclaration(writer, local);
@ -164,22 +212,28 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
boolean needBrace = bodyBlock.needsBraces(); boolean needBrace = bodyBlock.needsBraces();
switch (type) { switch (type) {
case WHILE: case WHILE:
writer.print("while ("+cond.simplify().toString()+")"); if (cond == TRUE)
/* special syntax for endless loops: */
writer.print("for (;;)");
else
writer.print("while ("+cond.simplify().toString()+")");
break; break;
case DOWHILE: case DOWHILE:
writer.print("do"); writer.print("do");
break; break;
case FOR: case FOR:
case POSSFOR:
writer.print("for ("); writer.print("for (");
if (isDeclaration) if (init != null) {
writer.print(((LocalStoreOperator) init.getOperator()) if (isDeclaration)
.getLocalInfo().getType().toString() writer.print(((LocalStoreOperator)
+ " " + init.simplify().toString()); init.getInstruction().getOperator())
else if (init != null) .getLocalInfo().getType().toString()
writer.print(init.simplify().toString()); + " ");
writer.print(init.getInstruction().simplify().toString());
}
writer.print("; "+cond.simplify().toString()+"; " writer.print("; "+cond.simplify().toString()+"; "
+incr.simplify().toString()+")"); +incr.getInstruction().simplify().toString()+")");
break; break;
} }
writer.println( needBrace?" {": ""); writer.println( needBrace?" {": "");
@ -255,8 +309,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
} }
public boolean doTransformations() { public boolean doTransformations() {
return type == FOR && init == null return init == null && (type == FOR || type == POSSFOR)
&& CreateForInitializer.transform(this, flowBlock.lastModified); && CreateForInitializer.transform(this, flowBlock.lastModified);
} }
} }

@ -97,12 +97,12 @@ public class SequentialBlock extends StructuredBlock {
*/ */
public void makeDeclaration(VariableSet done) { public void makeDeclaration(VariableSet done) {
/* A sequential block is special, since it doesn't declare /* A sequential block is special, since it doesn't declare
* any local Variable, but let the first sub block do this. * any local Variable, but lets the first sub block do this.
*/ */
declare = new VariableSet(); declare = new VariableSet();
subBlocks[0].used.addExact(used); subBlocks[0].used.unionExact(used);
subBlocks[0].makeDeclaration(done); subBlocks[0].makeDeclaration(done);
done.addExact(used); done.unionExact(used);
subBlocks[1].makeDeclaration(done); subBlocks[1].makeDeclaration(done);
} }

@ -291,7 +291,7 @@ public abstract class StructuredBlock {
/** /**
* Removes this block, or replaces it with an EmptyBlock. * Removes this block, or replaces it with an EmptyBlock.
*/ */
public void removeBlock() { public final void removeBlock() {
if (outer instanceof SequentialBlock) { if (outer instanceof SequentialBlock) {
if (outer.getSubBlocks()[1] == this) { if (outer.getSubBlocks()[1] == this) {
@ -325,8 +325,8 @@ public abstract class StructuredBlock {
/* All variables used in more than one sub blocks, are /* All variables used in more than one sub blocks, are
* used in this block, too. * used in this block, too.
*/ */
used.addExact(allUse.intersectExact(childUse)); used.unionExact(allUse.intersectExact(childUse));
allUse.addExact(childUse); allUse.unionExact(childUse);
} }
return allUse; return allUse;
} }
@ -346,7 +346,7 @@ public abstract class StructuredBlock {
declare.addElement(local); declare.addElement(local);
} }
declare.subtractExact(done); declare.subtractExact(done);
done.addExact(declare); done.unionExact(declare);
StructuredBlock[] subs = getSubBlocks(); StructuredBlock[] subs = getSubBlocks();
for (int i=0; i<subs.length; i++) for (int i=0; i<subs.length; i++)

@ -153,26 +153,6 @@ public class VariableSet extends java.util.Vector {
} }
} }
/**
* Add the other variable set to the current, except when the slot
* is already in the current set.
*/
public void addExact(VariableSet vs) {
int oldSize = elementCount;
iloop:
for (int i=0; i< vs.elementCount; i++) {
LocalInfo li2 = ((LocalInfo) vs.elementData[i]).getLocalInfo();
/* check if this slot was already overwritten by this block */
for (int j=0; j< oldSize; j++) {
LocalInfo li1 = (LocalInfo) elementData[j];
if (li1.getLocalInfo() == li2)
/* Yes it was, take next variable */
continue iloop;
}
addElement(li2);
}
}
/** /**
* Add the variables in gen to the current set, unless there are * Add the variables in gen to the current set, unless there are
* variables in kill using the same slot. * variables in kill using the same slot.

Loading…
Cancel
Save