*** 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. 235
      jode/jode/flow/FlowBlock.java
  3. 85
      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 =
((InstructionBlock) sequBlock.subBlocks[0]).getInstruction();
if (!(initializer.getOperator() instanceof StoreInstruction)
|| !initializer.getOperator().isVoid())
if (!initializer.getOperator().isVoid()
|| (forBlock.cond != forBlock.TRUE
&& !forBlock.cond.containsMatchingLoad(initializer)))
return false;
if (jode.Decompiler.isVerbose)
System.err.print('f');
forBlock.init = initializer;
forBlock.moveDefinitions(last.outer, null);
last.replace(last.outer);
forBlock.init = (InstructionBlock) sequBlock.subBlocks[0];
last.replace(sequBlock);
return true;
}
}

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

@ -33,6 +33,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public static final int WHILE = 0;
public static final int DOWHILE = 1;
public static final int FOR = 2;
public static final int POSSFOR = 3;
public static final Expression TRUE =
new ConstOperator(Type.tBoolean, "1");
@ -44,13 +45,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
*/
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.
@ -98,8 +99,43 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
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) {
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;
}
@ -111,6 +147,16 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
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.
* @param oldBlock the old sub block.
@ -136,11 +182,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
public void dumpDeclaration(TabbedPrintWriter writer, LocalInfo local)
throws java.io.IOException
{
if (type == FOR && init != null
if ((type == FOR || type == POSSFOR) && init != null
&& (outer == null || !outer.used.contains(local))
&& init.getOperator() instanceof LocalStoreOperator
&& ((LocalStoreOperator) init.getOperator()).getLocalInfo()
== local.getLocalInfo())
&& (init.getInstruction().getOperator()
instanceof LocalStoreOperator)
&& (((LocalStoreOperator)
init.getInstruction().getOperator()).getLocalInfo()
== local.getLocalInfo()))
isDeclaration = true;
else
super.dumpDeclaration(writer, local);
@ -164,22 +212,28 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
boolean needBrace = bodyBlock.needsBraces();
switch (type) {
case WHILE:
if (cond == TRUE)
/* special syntax for endless loops: */
writer.print("for (;;)");
else
writer.print("while ("+cond.simplify().toString()+")");
break;
case DOWHILE:
writer.print("do");
break;
case FOR:
case POSSFOR:
writer.print("for (");
if (init != null) {
if (isDeclaration)
writer.print(((LocalStoreOperator) init.getOperator())
writer.print(((LocalStoreOperator)
init.getInstruction().getOperator())
.getLocalInfo().getType().toString()
+ " " + init.simplify().toString());
else if (init != null)
writer.print(init.simplify().toString());
+ " ");
writer.print(init.getInstruction().simplify().toString());
}
writer.print("; "+cond.simplify().toString()+"; "
+incr.simplify().toString()+")");
+incr.getInstruction().simplify().toString()+")");
break;
}
writer.println( needBrace?" {": "");
@ -255,8 +309,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
}
public boolean doTransformations() {
return type == FOR && init == null
return init == null && (type == FOR || type == POSSFOR)
&& CreateForInitializer.transform(this, flowBlock.lastModified);
}
}

@ -97,12 +97,12 @@ public class SequentialBlock extends StructuredBlock {
*/
public void makeDeclaration(VariableSet done) {
/* 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();
subBlocks[0].used.addExact(used);
subBlocks[0].used.unionExact(used);
subBlocks[0].makeDeclaration(done);
done.addExact(used);
done.unionExact(used);
subBlocks[1].makeDeclaration(done);
}

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

Loading…
Cancel
Save