From df4c4560bb3a3f1c93be7de0c851374d2bd539da Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 31 Oct 1998 14:07:12 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@109 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/CreateForInitializer.java | 10 +- jode/jode/flow/FlowBlock.java | 231 ++++++++++++----------- jode/jode/flow/LoopBlock.java | 91 +++++++-- jode/jode/flow/SequentialBlock.java | 6 +- jode/jode/flow/StructuredBlock.java | 8 +- jode/jode/flow/VariableSet.java | 20 -- 6 files changed, 203 insertions(+), 163 deletions(-) diff --git a/jode/jode/flow/CreateForInitializer.java b/jode/jode/flow/CreateForInitializer.java index 8628841..293cfec 100644 --- a/jode/jode/flow/CreateForInitializer.java +++ b/jode/jode/flow/CreateForInitializer.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; } } diff --git a/jode/jode/flow/FlowBlock.java b/jode/jode/flow/FlowBlock.java index b5e65c0..64bcdd3 100644 --- a/jode/jode/flow/FlowBlock.java +++ b/jode/jode/flow/FlowBlock.java @@ -198,70 +198,75 @@ public class FlowBlock { ConditionalBlock cb = (ConditionalBlock) jump.prev.outer; 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 -// || (cb.outer instanceof SequentialBlock -// && cb.outer.getSubBlocks()[0] == cb -// && cb.outer.outer instanceof LoopBlock)) { + 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; + 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.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. -// */ + 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)) { + /* 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.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(); } diff --git a/jode/jode/flow/LoopBlock.java b/jode/jode/flow/LoopBlock.java index 9f45eab..4555cd4 100644 --- a/jode/jode/flow/LoopBlock.java +++ b/jode/jode/flow/LoopBlock.java @@ -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: - 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; case DOWHILE: writer.print("do"); break; case FOR: + case POSSFOR: writer.print("for ("); - if (isDeclaration) - writer.print(((LocalStoreOperator) init.getOperator()) - .getLocalInfo().getType().toString() - + " " + init.simplify().toString()); - else if (init != null) - writer.print(init.simplify().toString()); - + if (init != null) { + if (isDeclaration) + writer.print(((LocalStoreOperator) + init.getInstruction().getOperator()) + .getLocalInfo().getType().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); } } - diff --git a/jode/jode/flow/SequentialBlock.java b/jode/jode/flow/SequentialBlock.java index 762cdb6..064d0d7 100644 --- a/jode/jode/flow/SequentialBlock.java +++ b/jode/jode/flow/SequentialBlock.java @@ -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); } diff --git a/jode/jode/flow/StructuredBlock.java b/jode/jode/flow/StructuredBlock.java index 95c88d0..dc8c6dc 100644 --- a/jode/jode/flow/StructuredBlock.java +++ b/jode/jode/flow/StructuredBlock.java @@ -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