@ -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 )