fixed a bug, where some jumps were neither resolved nor put on remaining

list in resolveSomeJumps
END_OF_METHOD no longer can have predecessors
mapStackToLocals is more verbose on errors


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@502 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent ebbdf1e44f
commit 295632ab86
  1. 64
      jode/jode/flow/FlowBlock.java

@ -1,18 +1,18 @@
/* /* FlowBlock Copyright (C) 1998-1999 Jochen Hoenicke.
* FlowBlock (c) 1998 Jochen Hoenicke
* *
* You may distribute under the terms of the GNU General Public License. * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* *
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, * This program is distributed in the hope that it will be useful,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF * but WITHOUT ANY WARRANTY; without even the implied warranty of
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * GNU General Public License for more details.
* *
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * You should have received a copy of the GNU General Public License
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * along with this program; see the file COPYING. If not, write to
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* $Id$ * $Id$
*/ */
@ -463,14 +463,17 @@ public class FlowBlock {
for (StructuredBlock surrounder = jump.prev.outer; for (StructuredBlock surrounder = jump.prev.outer;
surrounder != null; surrounder = surrounder.outer) { surrounder != null; surrounder = surrounder.outer) {
if (surrounder instanceof BreakableBlock) { if (surrounder instanceof BreakableBlock) {
if (surrounder.getNextFlowBlock() != succ if (surrounder.getNextFlowBlock() == succ)
&& surrounder.jumpMayBeChanged()) { /* We can break to that block; this is done later. */
break;
if (surrounder.jumpMayBeChanged()) {
surrounder.setJump(new Jump(succ)); surrounder.setJump(new Jump(succ));
/* put surrounder in todo list */
surrounder.jump.next = jumps; surrounder.jump.next = jumps;
/* consider this jump again */
jumps = surrounder.jump; jumps = surrounder.jump;
continue next_jump; /* The break is inserted later */
break;
} }
if (succ == END_OF_METHOD) { if (succ == END_OF_METHOD) {
/* If the jump can be replaced by a return /* If the jump can be replaced by a return
@ -564,8 +567,10 @@ public class FlowBlock {
Jump hisJumps = (Jump) succs.nextElement(); Jump hisJumps = (Jump) succs.nextElement();
Jump myJumps = (Jump) successors.get(dest); Jump myJumps = (Jump) successors.get(dest);
if (dest != END_OF_METHOD)
dest.predecessors.removeElement(succ); dest.predecessors.removeElement(succ);
if (myJumps == null) { if (myJumps == null) {
if (dest != END_OF_METHOD)
dest.predecessors.addElement(this); dest.predecessors.addElement(this);
successors.put(dest, hisJumps); successors.put(dest, hisJumps);
} else { } else {
@ -696,7 +701,7 @@ public class FlowBlock {
Enumeration succs = successors.elements(); Enumeration succs = successors.elements();
while (keys.hasMoreElements()) { while (keys.hasMoreElements()) {
FlowBlock dest = (FlowBlock) keys.nextElement(); FlowBlock dest = (FlowBlock) keys.nextElement();
if (!dest.predecessors.contains(this)) if (dest.predecessors.contains(this) == (dest == END_OF_METHOD))
throw new AssertError("Inconsistency"); throw new AssertError("Inconsistency");
Jump jumps = (Jump)succs.nextElement(); Jump jumps = (Jump)succs.nextElement();
@ -776,11 +781,18 @@ public class FlowBlock {
*/ */
public void setNextByAddr(FlowBlock flow) { public void setNextByAddr(FlowBlock flow) {
Jump jumps = (Jump) successors.remove(NEXT_BY_ADDR); Jump jumps = (Jump) successors.remove(NEXT_BY_ADDR);
Jump flowJumps = (Jump) successors.get(flow);
if (jumps != null) { if (jumps != null) {
NEXT_BY_ADDR.predecessors.removeElement(this); NEXT_BY_ADDR.predecessors.removeElement(this);
for (Jump jump = jumps; jump != null; jump = jump.next) jumps.destination = flow;
jump.destination = flow; while (jumps.next != null) {
jumps = jumps.next;
jumps.destination = flow;
}
successors.put(flow, jumps); successors.put(flow, jumps);
if (flowJumps != null)
jumps.next = flowJumps;
else if (flow != END_OF_METHOD)
flow.predecessors.addElement(this); flow.predecessors.addElement(this);
} }
checkConsistent(); checkConsistent();
@ -1359,6 +1371,9 @@ public class FlowBlock {
(switchBlock.caseBlocks[last].subBlock); (switchBlock.caseBlocks[last].subBlock);
mergeSuccessors(lastFlow); mergeSuccessors(lastFlow);
} }
if (Decompiler.isFlowDebugging)
System.err.println("after analyzeSwitch: "+this);
checkConsistent(); checkConsistent();
return changed; return changed;
} }
@ -1392,7 +1407,7 @@ public class FlowBlock {
public void addSuccessor(Jump jump) { public void addSuccessor(Jump jump) {
jump.next = (Jump) successors.get(jump.destination); jump.next = (Jump) successors.get(jump.destination);
if (jump.next == null) if (jump.next == null && jump.destination != END_OF_METHOD)
jump.destination.predecessors.addElement(this); jump.destination.predecessors.addElement(this);
successors.put(jump.destination, jump); successors.put(jump.destination, jump);
@ -1426,11 +1441,9 @@ public class FlowBlock {
* didn't worked. * didn't worked.
*/ */
public void mapStackToLocal(VariableStack initialStack) { public void mapStackToLocal(VariableStack initialStack) {
if (stackMap != null) { if (initialStack == null)
stackMap.merge(initialStack); throw new jode.AssertError("initial stack is null");
} else
stackMap = initialStack; stackMap = initialStack;
block.mapStackToLocal(initialStack); block.mapStackToLocal(initialStack);
Enumeration enum = successors.elements(); Enumeration enum = successors.elements();
while (enum.hasMoreElements()) { while (enum.hasMoreElements()) {
@ -1439,6 +1452,9 @@ public class FlowBlock {
FlowBlock succ = jumps.destination; FlowBlock succ = jumps.destination;
stack = succ.stackMap; stack = succ.stackMap;
for (/**/; jumps != null; jumps = jumps.next) { for (/**/; jumps != null; jumps = jumps.next) {
if (jumps.stackMap == null)
System.err.println("Dead jump? "+jumps.prev+" in "+this);
stack = VariableStack.merge(stack, jumps.stackMap); stack = VariableStack.merge(stack, jumps.stackMap);
} }
if (succ.stackMap == null) if (succ.stackMap == null)

Loading…
Cancel
Save