fixed all remaining bugs, I hope ...

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@77 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 2dad930eb6
commit e2b966818c
  1. 127
      jode/jode/flow/FlowBlock.java

@ -122,9 +122,15 @@ public class FlowBlock {
* @param jumps The jumps that jump to successor. All jumps that * @param jumps The jumps that jump to successor. All jumps that
* can be optimized are removed from this stack. * can be optimized are removed from this stack.
*/ */
public void optimizeJumps(Stack jumps) { public void optimizeJumps(Stack jumps, FlowBlock succ) {
Stack remainingJumps = new Stack(); Stack remainingJumps = new Stack();
if (lastModified.jump == null) {
Jump jump = new Jump(succ);
lastModified.setJump(jump);
remainingJumps.push(jump);
}
next_jump: next_jump:
while (!jumps.isEmpty()) { while (!jumps.isEmpty()) {
Jump jump = (Jump) jumps.pop(); Jump jump = (Jump) jumps.pop();
@ -206,7 +212,7 @@ public class FlowBlock {
(loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
|| loopBlock.getNextFlowBlock() == successor)) { || loopBlock.getNextFlowBlock() == successor)) {
if (loopBlock.jumpMayBeChanged()) { if (loopBlock.jump == null) {
loopBlock.moveJump(jump); loopBlock.moveJump(jump);
jumps.push(jump); jumps.push(jump);
} else } else
@ -240,7 +246,7 @@ public class FlowBlock {
(loopBlock.jumpMayBeChanged() (loopBlock.jumpMayBeChanged()
|| loopBlock.getNextFlowBlock() == successor)) { || loopBlock.getNextFlowBlock() == successor)) {
if (loopBlock.jumpMayBeChanged()) { if (loopBlock.jump == null) {
loopBlock.moveJump(jump); loopBlock.moveJump(jump);
jumps.push(jump); jumps.push(jump);
} else } else
@ -274,8 +280,7 @@ public class FlowBlock {
newIfBlock.setThenBlock(thenBlock); newIfBlock.setThenBlock(thenBlock);
if (thenBlock.contains(lastModified)) { if (thenBlock.contains(lastModified)) {
if (lastModified.jump != null if (lastModified.jump.destination == successor) {
&& lastModified.jump.destination == successor) {
newIfBlock.moveJump(lastModified.jump); newIfBlock.moveJump(lastModified.jump);
lastModified = newIfBlock; lastModified = newIfBlock;
jump.prev.removeJump(); jump.prev.removeJump();
@ -327,8 +332,7 @@ public class FlowBlock {
ifBlock.setElseBlock(elseBlock); ifBlock.setElseBlock(elseBlock);
if (elseBlock.contains(lastModified)) { if (elseBlock.contains(lastModified)) {
if (lastModified.jump != null if (lastModified.jump.destination == successor) {
&& lastModified.jump.destination == successor) {
ifBlock.moveJump(lastModified.jump); ifBlock.moveJump(lastModified.jump);
lastModified = ifBlock; lastModified = ifBlock;
jump.prev.removeJump(); jump.prev.removeJump();
@ -617,7 +621,7 @@ public class FlowBlock {
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps); optimizeJumps(jumps, succ);
resolveRemaining(jumps); resolveRemaining(jumps);
/* Now unify the blocks. /* Now unify the blocks.
@ -737,7 +741,7 @@ public class FlowBlock {
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps); optimizeJumps(jumps, this);
LoopBlock whileBlock = LoopBlock whileBlock =
new LoopBlock(LoopBlock.WHILE, LoopBlock.TRUE); new LoopBlock(LoopBlock.WHILE, LoopBlock.TRUE);
@ -751,7 +755,7 @@ public class FlowBlock {
while (!jumps.isEmpty()) { while (!jumps.isEmpty()) {
Jump jump = (Jump) jumps.pop(); Jump jump = (Jump) jumps.pop();
if (jump.prev == bodyBlock) if (jump.prev == lastModified)
/* handled later */ /* handled later */
continue; continue;
@ -780,11 +784,10 @@ public class FlowBlock {
(new BreakBlock(breakToBlock, breaklevel > 1)); (new BreakBlock(breakToBlock, breaklevel > 1));
} }
/* Now remove the jump of bodyBlock if it points to this. /* Now remove the jump of lastModified if it points to this.
*/ */
if (bodyBlock.jump != null if (lastModified.jump.destination == this)
&& bodyBlock.jump.destination == this) lastModified.removeJump();
bodyBlock.removeJump();
} }
/* remove ourself from the predecessor list. /* remove ourself from the predecessor list.
@ -805,11 +808,13 @@ public class FlowBlock {
public void mergeEndBlock() { public void mergeEndBlock() {
checkConsistent(); checkConsistent();
/* First find the innermost block that contains all jumps to the Stack allJumps = (Stack) successors.remove(END_OF_METHOD);
* END_OF_METHOD block. if (allJumps == null)
return;
/* First remove all implicit jumps to the END_OF_METHOD block.
*/ */
Stack jumps = new Stack(); Stack jumps = new Stack();
Stack allJumps = (Stack) successors.remove(END_OF_METHOD);
Enumeration enum = allJumps.elements(); Enumeration enum = allJumps.elements();
while (enum.hasMoreElements()) { while (enum.hasMoreElements()) {
Jump jump = (Jump) enum.nextElement(); Jump jump = (Jump) enum.nextElement();
@ -824,7 +829,7 @@ public class FlowBlock {
/* Try to eliminate as many jumps as possible. /* Try to eliminate as many jumps as possible.
*/ */
optimizeJumps(jumps); optimizeJumps(jumps, END_OF_METHOD);
next_jump: next_jump:
while (!jumps.isEmpty()) { while (!jumps.isEmpty()) {
@ -863,8 +868,7 @@ public class FlowBlock {
/* Now remove the jump of the lastModified if it points to /* Now remove the jump of the lastModified if it points to
* END_OF_METHOD. * END_OF_METHOD.
*/ */
if (lastModified.jump != null if (lastModified.jump.destination == END_OF_METHOD)
&& lastModified.jump.destination == END_OF_METHOD)
lastModified.removeJump(); lastModified.removeJump();
/* transformation succeeded */ /* transformation succeeded */
@ -1327,9 +1331,11 @@ public class FlowBlock {
if (tryFlow == catchFlow) if (tryFlow == catchFlow)
throw new AssertError("try == catch"); throw new AssertError("try == catch");
checkConsistent();
boolean changed = false; boolean changed = false;
while(tryFlow.analyze(addr, catchFlow.addr)); while(tryFlow.analyze(addr, catchFlow.addr));
while(catchFlow.analyze(catchFlow.addr, end)); while(catchFlow.analyze(catchFlow.addr, end));
checkConsistent();
updateInOut(tryFlow, true, (Stack) successors.remove(tryFlow)); updateInOut(tryFlow, true, (Stack) successors.remove(tryFlow));
updateInOut(catchFlow, true, (Stack) successors.remove(catchFlow)); updateInOut(catchFlow, true, (Stack) successors.remove(catchFlow));
@ -1410,7 +1416,9 @@ public class FlowBlock {
((LocalLoadOperator)monexit.getSubExpressions()[0]) ((LocalLoadOperator)monexit.getSubExpressions()[0])
.getLocalInfo(); .getLocalInfo();
checkAndRemoveMonitorExit(local, end); length -= tryFlow.length;
tryFlow.checkAndRemoveMonitorExit(local, end);
length += tryFlow.length;
SynchronizedBlock syncBlock = new SynchronizedBlock(local); SynchronizedBlock syncBlock = new SynchronizedBlock(local);
syncBlock.replace(rawBlock, rawBlock); syncBlock.replace(rawBlock, rawBlock);
@ -1475,7 +1483,7 @@ public class FlowBlock {
if (subRoutine.successors.size() != 0) if (subRoutine.successors.size() != 0)
throw new AssertError("Jump inside subroutine"); throw new AssertError("Jump inside subroutine");
length += subRoutine.length; length += subRoutine.length;
checkAndRemoveJSR(subRoutine); tryFlow.checkAndRemoveJSR(subRoutine);
CatchFinallyBlock newBlock = new CatchFinallyBlock(); CatchFinallyBlock newBlock = new CatchFinallyBlock();
newBlock.replace(rawBlock, rawBlock); newBlock.replace(rawBlock, rawBlock);
@ -1491,50 +1499,53 @@ public class FlowBlock {
&& ((InstructionBlock) catchFlow.block).getInstruction() && ((InstructionBlock) catchFlow.block).getInstruction()
instanceof PopOperator instanceof PopOperator
&& ((PopOperator) ((InstructionBlock) catchFlow.block) && ((PopOperator) ((InstructionBlock) catchFlow.block)
.getInstruction()).getCount() == 1 .getInstruction()).getCount() == 1) {
&& successors.size() == 1) {
/* This is a special try/finally-block, where /* This is a special try/finally-block, where
* the finally block ends with a break, return or * the finally block ends with a break, return or
* similar. * similar.
*/ */
FlowBlock succ = catchFlow.block.jump.destination; FlowBlock succ = catchFlow.block.jump.destination;
Stack jumps = (Stack) successors.remove(succ); Stack jumps = (Stack) tryFlow.successors.remove(succ);
updateInOut(succ, true, jumps); if (tryFlow.successors.size() > 0) {
/* Only do the rest if tryFlow has no other exit point,
Stack stack = new Stack(); * undo the previous remove.
stack.push(catchFlow.block.jump); */
successors.put(succ, stack); tryFlow.successors.put(succ,jumps);
jumps.removeElement(catchFlow.block.jump);
if (rawBlock.tryBlock.jump == null) {
Jump jump = new Jump(succ);
rawBlock.tryBlock.setJump(jump);
jumps.push(jump);
}
lastModified = tryFlow.lastModified;
optimizeJumps(jumps);
resolveRemaining(jumps);
CatchFinallyBlock newBlock = new CatchFinallyBlock();
newBlock.replace(rawBlock, rawBlock);
newBlock.setTryBlock(rawBlock.tryBlock);
if (succ.predecessors.size() == 1) {
while (succ.analyze(addr+length, end));
length += succ.length;
successors.remove(succ);
newBlock.setFinallyBlock(succ.block);
mergeSuccessors(succ);
} else { } else {
/* The finally block is empty, put the jump back
* into the finally block. succ.predecessors.removeElement(tryFlow);
/* Handle the jumps in the tryFlow. Note that
* we call updateInOut on ourself, don't change it.
*/ */
newBlock.setFinallyBlock(new EmptyBlock()); updateInOut(succ, true, jumps);
newBlock.finallyBlock.moveJump(catchFlow.block.jump); tryFlow.optimizeJumps(jumps, succ);
tryFlow.resolveRemaining(jumps);
CatchFinallyBlock newBlock = new CatchFinallyBlock();
newBlock.replace(rawBlock, rawBlock);
newBlock.setTryBlock(tryFlow.block);
/* try block has no successors */
if (succ.predecessors.size() == 1) {
while (succ.analyze(addr+length, end));
length += succ.length;
successors.remove(succ);
newBlock.setFinallyBlock(succ.block);
mergeSuccessors(succ);
} else {
/* The finally block is empty, put the jump back
* into the finally block.
*/
newBlock.setFinallyBlock
(new EmptyBlock(catchFlow.block.jump));
mergeSuccessors(catchFlow);
}
lastModified = newBlock;
changed = true;
} }
lastModified = newBlock;
changed = true;
} }
checkConsistent(); checkConsistent();
if (Decompiler.debugAnalyze) if (Decompiler.debugAnalyze)
@ -1628,7 +1639,7 @@ public class FlowBlock {
updateInOut(nextFlow, true, lastJumps); updateInOut(nextFlow, true, lastJumps);
lastJumps.pop(); lastJumps.pop();
lastFlow.optimizeJumps(lastJumps); lastFlow.optimizeJumps(lastJumps, nextFlow);
lastFlow.resolveRemaining(lastJumps); lastFlow.resolveRemaining(lastJumps);
} else } else
updateInOut(nextFlow, true, jumps); updateInOut(nextFlow, true, jumps);
@ -1709,7 +1720,7 @@ public class FlowBlock {
destJumps = new Stack(); destJumps = new Stack();
successors.put(jump.destination, destJumps); successors.put(jump.destination, destJumps);
} }
destJumps.addElement(jump); destJumps.push(jump);
} }
public void makeDeclaration(VariableSet param) { public void makeDeclaration(VariableSet param) {

Loading…
Cancel
Save