|
|
@ -26,9 +26,18 @@ import jode.decompiler.MethodAnalyzer; |
|
|
|
import jode.decompiler.LocalInfo; |
|
|
|
import jode.decompiler.LocalInfo; |
|
|
|
import jode.expr.Expression; |
|
|
|
import jode.expr.Expression; |
|
|
|
import jode.expr.CombineableOperator; |
|
|
|
import jode.expr.CombineableOperator; |
|
|
|
import jode.util.SimpleDictionary; |
|
|
|
import jode.util.SimpleMap; |
|
|
|
import jode.util.SimpleSet; |
|
|
|
import jode.util.SimpleSet; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///#ifdef JDK12
|
|
|
|
|
|
|
|
///import java.util.Map;
|
|
|
|
|
|
|
|
///import java.util.Iterator;
|
|
|
|
|
|
|
|
///#else
|
|
|
|
|
|
|
|
import jode.util.Map; |
|
|
|
|
|
|
|
import jode.util.Iterator; |
|
|
|
|
|
|
|
///#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A flow block is the structure of which the flow graph consists. A |
|
|
|
* A flow block is the structure of which the flow graph consists. A |
|
|
|
* flow block contains structured code together with some conditional |
|
|
|
* flow block contains structured code together with some conditional |
|
|
@ -100,11 +109,11 @@ public class FlowBlock { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* This contains a map of all successing flow blocks and there |
|
|
|
* This contains a map of all successing flow blocks and there |
|
|
|
* jumps. The key of this dictionary are the flow blocks, while |
|
|
|
* jumps. The key of this map are the flow blocks, while |
|
|
|
* the elements is the first jump to that flow block. The other |
|
|
|
* the elements is the first jump to that flow block. The other |
|
|
|
* jumps are accessible via the jump.next field. |
|
|
|
* jumps are accessible via the jump.next field. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Dictionary successors = new SimpleDictionary(); |
|
|
|
Map successors = new SimpleMap(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* This is a vector of flow blocks, which reference this block. |
|
|
|
* This is a vector of flow blocks, which reference this block. |
|
|
@ -566,11 +575,11 @@ public class FlowBlock { |
|
|
|
void mergeSuccessors(FlowBlock succ) { |
|
|
|
void mergeSuccessors(FlowBlock succ) { |
|
|
|
/* Merge the sucessors from the successing flow block |
|
|
|
/* Merge the sucessors from the successing flow block |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Enumeration keys = succ.successors.keys(); |
|
|
|
Iterator iter = succ.successors.entrySet().iterator(); |
|
|
|
Enumeration succs = succ.successors.elements(); |
|
|
|
while (iter.hasNext()) { |
|
|
|
while (keys.hasMoreElements()) { |
|
|
|
Map.Entry entry = (Map.Entry) iter.next(); |
|
|
|
FlowBlock dest = (FlowBlock) keys.nextElement(); |
|
|
|
FlowBlock dest = (FlowBlock) entry.getKey(); |
|
|
|
Jump hisJumps = (Jump) succs.nextElement(); |
|
|
|
Jump hisJumps = (Jump) entry.getValue(); |
|
|
|
Jump myJumps = (Jump) successors.get(dest); |
|
|
|
Jump myJumps = (Jump) successors.get(dest); |
|
|
|
|
|
|
|
|
|
|
|
if (dest != END_OF_METHOD) |
|
|
|
if (dest != END_OF_METHOD) |
|
|
@ -646,9 +655,9 @@ public class FlowBlock { |
|
|
|
|
|
|
|
|
|
|
|
/* The gen/kill sets must be updated for every jump |
|
|
|
/* The gen/kill sets must be updated for every jump |
|
|
|
* in the other block */ |
|
|
|
* in the other block */ |
|
|
|
Enumeration succSuccs = successor.successors.elements(); |
|
|
|
Iterator succSuccs = successor.successors.values().iterator(); |
|
|
|
while (succSuccs.hasMoreElements()) { |
|
|
|
while (succSuccs.hasNext()) { |
|
|
|
Jump succJumps = (Jump) succSuccs.nextElement(); |
|
|
|
Jump succJumps = (Jump) succSuccs.next(); |
|
|
|
for (; succJumps != null; succJumps = succJumps.next) { |
|
|
|
for (; succJumps != null; succJumps = succJumps.next) { |
|
|
|
|
|
|
|
|
|
|
|
succJumps.gen.mergeGenKill(gens, succJumps.kill); |
|
|
|
succJumps.gen.mergeGenKill(gens, succJumps.kill); |
|
|
@ -703,14 +712,14 @@ public class FlowBlock { |
|
|
|
if (last.outer != null) |
|
|
|
if (last.outer != null) |
|
|
|
throw new AssertError("Inconsistency"); |
|
|
|
throw new AssertError("Inconsistency"); |
|
|
|
|
|
|
|
|
|
|
|
Enumeration keys = successors.keys(); |
|
|
|
Iterator iter = successors.entrySet().iterator(); |
|
|
|
Enumeration succs = successors.elements(); |
|
|
|
while (iter.hasNext()) { |
|
|
|
while (keys.hasMoreElements()) { |
|
|
|
Map.Entry entry = (Map.Entry) iter.next(); |
|
|
|
FlowBlock dest = (FlowBlock) keys.nextElement(); |
|
|
|
FlowBlock dest = (FlowBlock) entry.getKey(); |
|
|
|
if (dest.predecessors.contains(this) == (dest == END_OF_METHOD)) |
|
|
|
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)entry.getValue(); |
|
|
|
if (jumps == null) |
|
|
|
if (jumps == null) |
|
|
|
throw new AssertError("Inconsistency"); |
|
|
|
throw new AssertError("Inconsistency"); |
|
|
|
|
|
|
|
|
|
|
@ -1159,10 +1168,10 @@ public class FlowBlock { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
FlowBlock getSuccessor(int start, int end) { |
|
|
|
FlowBlock getSuccessor(int start, int end) { |
|
|
|
/* search successor with smallest addr. */ |
|
|
|
/* search successor with smallest addr. */ |
|
|
|
Enumeration keys = successors.keys(); |
|
|
|
Iterator keys = successors.keySet().iterator(); |
|
|
|
FlowBlock succ = null; |
|
|
|
FlowBlock succ = null; |
|
|
|
while (keys.hasMoreElements()) { |
|
|
|
while (keys.hasNext()) { |
|
|
|
FlowBlock fb = (FlowBlock) keys.nextElement(); |
|
|
|
FlowBlock fb = (FlowBlock) keys.next(); |
|
|
|
if (fb.addr < start || fb.addr >= end || fb == this) |
|
|
|
if (fb.addr < start || fb.addr >= end || fb == this) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
if (succ == null || fb.addr < succ.addr) { |
|
|
|
if (succ == null || fb.addr < succ.addr) { |
|
|
@ -1451,9 +1460,9 @@ public class FlowBlock { |
|
|
|
throw new jode.AssertError("initial stack is null"); |
|
|
|
throw new jode.AssertError("initial stack is null"); |
|
|
|
stackMap = initialStack; |
|
|
|
stackMap = initialStack; |
|
|
|
block.mapStackToLocal(initialStack); |
|
|
|
block.mapStackToLocal(initialStack); |
|
|
|
Enumeration enum = successors.elements(); |
|
|
|
Iterator iter = successors.values().iterator(); |
|
|
|
while (enum.hasMoreElements()) { |
|
|
|
while (iter.hasNext()) { |
|
|
|
Jump jumps = (Jump) enum.nextElement(); |
|
|
|
Jump jumps = (Jump) iter.next(); |
|
|
|
VariableStack stack; |
|
|
|
VariableStack stack; |
|
|
|
FlowBlock succ = jumps.destination; |
|
|
|
FlowBlock succ = jumps.destination; |
|
|
|
if (succ == END_OF_METHOD) |
|
|
|
if (succ == END_OF_METHOD) |
|
|
@ -1477,9 +1486,9 @@ public class FlowBlock { |
|
|
|
return; |
|
|
|
return; |
|
|
|
stackMap = null; |
|
|
|
stackMap = null; |
|
|
|
block.removePush(); |
|
|
|
block.removePush(); |
|
|
|
Enumeration enum = successors.keys(); |
|
|
|
Iterator iter = successors.keySet().iterator(); |
|
|
|
while (enum.hasMoreElements()) { |
|
|
|
while (iter.hasNext()) { |
|
|
|
FlowBlock succ = (FlowBlock)enum.nextElement(); |
|
|
|
FlowBlock succ = (FlowBlock)iter.next(); |
|
|
|
succ.removePush(); |
|
|
|
succ.removePush(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|