Handle empty blocks used for "while(true) {}"

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1362 379699f6-c40d-0410-875b-85095c16579e
master
hoenicke 23 years ago
parent d7567a6b06
commit c11b2426df
  1. 11
      jode/ChangeLog
  2. 35
      jode/src/net/sf/jode/bytecode/BasicBlockReader.java
  3. 10
      jode/src/net/sf/jode/decompiler/MethodAnalyzer.java

@ -1,3 +1,14 @@
2002-02-15 Jochen Hoenicke <jochen@gnu.org>
* net/sf/jode/bytecode/BasicBlockReader.java: handle empty loops.
(IS_NULL): new constant to tag empty blocks.
(markReachableBlocks): check for empty loops.
(convertBlock): Handle empty blocks.
(convert): Handle IS_NULL.
* net/sf/jode/decompiler/MethodAnalyzer.java:
(analyzeCode): handle empty blocks.
2001-08-14 Jochen Hoenicke <jochen@gnu.org>
* build.xml: test is default.

@ -39,6 +39,7 @@ class BasicBlockReader implements Opcodes {
static final int IS_REACHABLE = 2;
static final int IS_FORWARD = 4;
static final int IS_CATCHER = 8;
static final int IS_NULL = 16;
private class InstrInfo {
Instruction instr;
@ -97,9 +98,21 @@ class BasicBlockReader implements Opcodes {
&& (info.instr.getOpcode() == opc_goto
|| (info.instr.getOpcode() == opc_return
&& info.stack == 0))) {
/* This is a forward block.
/* This is a forward block. We need to check for loops,
* though.
*/
info.flags |= IS_FORWARD;
InstrInfo succ = info;
do {
if (succ.instr.getOpcode() == opc_return) {
succ = null;
break;
}
succ = infos[info.succs[0]];
} while ((succ.flags & IS_FORWARD) != 0);
if (succ == info)
info.flags |= IS_NULL;
else
info.flags |= IS_FORWARD;
} else {
// Check for reachable exception handlers
for (int i=0; i < handlers.length; i++) {
@ -240,15 +253,15 @@ class BasicBlockReader implements Opcodes {
private void convertBlock(int firstAddr, int count) {
Instruction[] instrs = new Instruction[count];
InstrInfo info = infos[firstAddr];
int blockNr = info.blockNr;
instrs[0] = info.instr;
for (int i=1; i < count; i++) {
info = infos[info.nextAddr];
for (int i = 0; i < count; i++) {
if (i > 0)
info = infos[info.nextAddr];
instrs[i] = info.instr;
}
int[] lastSuccs = info.succs;
int succLength = lastSuccs != null ? lastSuccs.length : 0;
boolean alwaysJump = info.instr.doesAlwaysJump();
@ -292,8 +305,12 @@ class BasicBlockReader implements Opcodes {
start = -1;
}
if ((info.flags & (IS_REACHABLE | IS_FORWARD)) == IS_REACHABLE) {
start = i;
count = 0;
if ((info.flags & IS_NULL) != 0) {
convertBlock(i, 0);
} else {
start = i;
count = 0;
}
}
if (start != -1)
count++;

@ -475,9 +475,8 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
int count = 0;
for (int i=0; i < blocks.length; i++) {
int mark = 100;
int last = blocks[i].getInstructions().length - 1;
for (int j=0; j <= last; j++) {
Instruction instr = blocks[i].getInstructions()[j];
Instruction[] instrs = blocks[i].getInstructions();
for (int j=0; j < instrs.length; j++) {
if (GlobalOptions.verboseLevel > 0 && j > mark) {
GlobalOptions.err.print('.');
mark += 100;
@ -487,11 +486,12 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
pl.updateProgress(done, methodName);
count = 0;
}
Opcodes.addOpcode(flows[i], instr, this);
Opcodes.addOpcode(flows[i], instrs[j], this);
}
Block[] succs = blocks[i].getSuccs();
FlowBlock[] flowSuccs;
int lastOpcode = blocks[i].getInstructions()[last].getOpcode();
int lastOpcode = instrs.length > 0
? instrs[instrs.length-1].getOpcode() : Opcodes.opc_nop;
if (lastOpcode >= Opcodes.opc_ireturn
&& lastOpcode <= Opcodes.opc_areturn) {
flowSuccs = new FlowBlock[] { FlowBlock.END_OF_METHOD };

Loading…
Cancel
Save